-- ============================================================
-- 001_ChannelConfig.sql
-- Move channel provider configuration from appsettings.json 
-- into database-driven configuration.
-- ============================================================

-- ── Table ──────────────────────────────────────────────────

IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'tbChannelConfig')
BEGIN
    CREATE TABLE dbo.tbChannelConfig (
        chcChannelType              VARCHAR(50)     NOT NULL PRIMARY KEY,
        chcDisplayName              NVARCHAR(100)   NOT NULL,
        chcDescription              NVARCHAR(500)   NULL,
        chcIcon                     VARCHAR(50)     NULL,
        chcColor                    VARCHAR(20)     NULL,
        chcEnabled                  BIT             NOT NULL DEFAULT 1,
        chcIsStub                   BIT             NOT NULL DEFAULT 1,
        chcEndpoint                 VARCHAR(500)    NULL,
        chcInternalKey              VARCHAR(500)    NULL,
        chcMinDailyBudget           DECIMAL(10,2)   NOT NULL DEFAULT 5.00,
        chcMinMonthlyBudget         DECIMAL(10,2)   NOT NULL DEFAULT 150.00,
        chcSupportedObjectives      NVARCHAR(500)   NULL,   -- JSON array: ["sales","leads","traffic"]
        chcSupportedCreativeFormats NVARCHAR(500)   NULL,   -- JSON array: ["text","image","video"]
        chcApprovalEstimateHours    INT             NOT NULL DEFAULT 24,
        chcMetricsRefreshIntervalMinutes INT        NOT NULL DEFAULT 60,
        chcAuthMethod               VARCHAR(50)     NULL,
        chcKeyVaultSecretName       VARCHAR(200)    NULL,
        chcStatusMappings           NVARCHAR(MAX)   NULL,   -- JSON object: {"ENABLED":"active",...}
        chcSortOrder                INT             NOT NULL DEFAULT 0,
        chcCreatedAt                DATETIME2       NOT NULL DEFAULT GETUTCDATE(),
        chcUpdatedAt                DATETIME2       NOT NULL DEFAULT GETUTCDATE()
    );
    PRINT 'Created table tbChannelConfig';
END
GO

-- ── Stored Procedure ───────────────────────────────────────

CREATE OR ALTER PROCEDURE dbo.spChannelConfig
    @action VARCHAR(50),
    @rqst   NVARCHAR(MAX) = '{}',
    @resp   NVARCHAR(MAX) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    -- ── list: return all enabled channels ──
    IF @action = 'list'
    BEGIN
        SET @resp = (
            SELECT
                chcChannelType          AS channelType,
                chcDisplayName          AS displayName,
                chcDescription          AS [description],
                chcIcon                 AS icon,
                chcColor                AS color,
                chcEnabled              AS [enabled],
                chcIsStub               AS isStub,
                chcEndpoint             AS endpoint,
                chcInternalKey          AS internalKey,
                chcMinDailyBudget       AS minDailyBudget,
                chcMinMonthlyBudget     AS minMonthlyBudget,
                JSON_QUERY(chcSupportedObjectives)      AS supportedObjectives,
                JSON_QUERY(chcSupportedCreativeFormats)  AS supportedCreativeFormats,
                chcApprovalEstimateHours               AS approvalEstimateHours,
                chcMetricsRefreshIntervalMinutes        AS metricsRefreshIntervalMinutes,
                chcAuthMethod           AS authMethod,
                chcKeyVaultSecretName   AS keyVaultSecretName,
                JSON_QUERY(chcStatusMappings)           AS statusMappings,
                chcSortOrder            AS sortOrder
            FROM dbo.tbChannelConfig
            ORDER BY chcSortOrder, chcChannelType
            FOR JSON PATH
        );

        IF @resp IS NULL SET @resp = '[]';
        SET @resp = '{"ok":true,"channels":' + @resp + '}';
        RETURN;
    END

    -- ── listAll: return all channels including disabled (for admin) ──
    IF @action = 'listAll'
    BEGIN
        SET @resp = (
            SELECT
                chcChannelType          AS channelType,
                chcDisplayName          AS displayName,
                chcDescription          AS [description],
                chcIcon                 AS icon,
                chcColor                AS color,
                chcEnabled              AS [enabled],
                chcIsStub               AS isStub,
                chcEndpoint             AS endpoint,
                chcMinDailyBudget       AS minDailyBudget,
                chcMinMonthlyBudget     AS minMonthlyBudget,
                JSON_QUERY(chcSupportedObjectives)      AS supportedObjectives,
                JSON_QUERY(chcSupportedCreativeFormats)  AS supportedCreativeFormats,
                chcApprovalEstimateHours               AS approvalEstimateHours,
                chcMetricsRefreshIntervalMinutes        AS metricsRefreshIntervalMinutes,
                chcAuthMethod           AS authMethod,
                chcKeyVaultSecretName   AS keyVaultSecretName,
                JSON_QUERY(chcStatusMappings)           AS statusMappings,
                chcSortOrder            AS sortOrder,
                chcCreatedAt            AS createdAt,
                chcUpdatedAt            AS updatedAt
            FROM dbo.tbChannelConfig
            ORDER BY chcSortOrder, chcChannelType
            FOR JSON PATH
        );

        IF @resp IS NULL SET @resp = '[]';
        SET @resp = '{"ok":true,"channels":' + @resp + '}';
        RETURN;
    END

    -- ── get: return single channel by type ──
    IF @action = 'get'
    BEGIN
        DECLARE @channelType VARCHAR(50) = JSON_VALUE(@rqst, '$.channelType');

        IF NOT EXISTS (SELECT 1 FROM dbo.tbChannelConfig WHERE chcChannelType = @channelType)
        BEGIN
            SET @resp = '{"ok":false,"error":"Channel not found"}';
            RETURN;
        END

        SET @resp = (
            SELECT
                chcChannelType          AS channelType,
                chcDisplayName          AS displayName,
                chcDescription          AS [description],
                chcIcon                 AS icon,
                chcColor                AS color,
                chcEnabled              AS [enabled],
                chcIsStub               AS isStub,
                chcEndpoint             AS endpoint,
                chcMinDailyBudget       AS minDailyBudget,
                chcMinMonthlyBudget     AS minMonthlyBudget,
                JSON_QUERY(chcSupportedObjectives)      AS supportedObjectives,
                JSON_QUERY(chcSupportedCreativeFormats)  AS supportedCreativeFormats,
                chcApprovalEstimateHours               AS approvalEstimateHours,
                chcMetricsRefreshIntervalMinutes        AS metricsRefreshIntervalMinutes,
                chcAuthMethod           AS authMethod,
                chcKeyVaultSecretName   AS keyVaultSecretName,
                JSON_QUERY(chcStatusMappings)           AS statusMappings
            FROM dbo.tbChannelConfig
            WHERE chcChannelType = @channelType
            FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
        );

        SET @resp = '{"ok":true,"channel":' + @resp + '}';
        RETURN;
    END

    -- ── upsert: create or update a channel (admin) ──
    IF @action = 'upsert'
    BEGIN
        DECLARE @uChannelType VARCHAR(50) = JSON_VALUE(@rqst, '$.channelType');

        IF @uChannelType IS NULL
        BEGIN
            SET @resp = '{"ok":false,"error":"channelType is required"}';
            RETURN;
        END

        MERGE dbo.tbChannelConfig AS tgt
        USING (SELECT @uChannelType AS chcChannelType) AS src
        ON tgt.chcChannelType = src.chcChannelType
        WHEN MATCHED THEN
            UPDATE SET
                chcDisplayName              = ISNULL(JSON_VALUE(@rqst, '$.displayName'),          tgt.chcDisplayName),
                chcDescription              = ISNULL(JSON_VALUE(@rqst, '$.description'),          tgt.chcDescription),
                chcIcon                     = ISNULL(JSON_VALUE(@rqst, '$.icon'),                 tgt.chcIcon),
                chcColor                    = ISNULL(JSON_VALUE(@rqst, '$.color'),                tgt.chcColor),
                chcEnabled                  = ISNULL(CAST(JSON_VALUE(@rqst, '$.enabled') AS BIT), tgt.chcEnabled),
                chcIsStub                   = ISNULL(CAST(JSON_VALUE(@rqst, '$.isStub') AS BIT),  tgt.chcIsStub),
                chcEndpoint                 = CASE WHEN JSON_VALUE(@rqst, '$.endpoint') IS NOT NULL
                                                   THEN JSON_VALUE(@rqst, '$.endpoint')
                                                   ELSE tgt.chcEndpoint END,
                chcInternalKey              = CASE WHEN JSON_VALUE(@rqst, '$.internalKey') IS NOT NULL
                                                   THEN JSON_VALUE(@rqst, '$.internalKey')
                                                   ELSE tgt.chcInternalKey END,
                chcMinDailyBudget           = ISNULL(CAST(JSON_VALUE(@rqst, '$.minDailyBudget') AS DECIMAL(10,2)),       tgt.chcMinDailyBudget),
                chcMinMonthlyBudget         = ISNULL(CAST(JSON_VALUE(@rqst, '$.minMonthlyBudget') AS DECIMAL(10,2)),     tgt.chcMinMonthlyBudget),
                chcSupportedObjectives      = CASE WHEN JSON_QUERY(@rqst, '$.supportedObjectives') IS NOT NULL
                                                   THEN JSON_QUERY(@rqst, '$.supportedObjectives')
                                                   ELSE tgt.chcSupportedObjectives END,
                chcSupportedCreativeFormats = CASE WHEN JSON_QUERY(@rqst, '$.supportedCreativeFormats') IS NOT NULL
                                                   THEN JSON_QUERY(@rqst, '$.supportedCreativeFormats')
                                                   ELSE tgt.chcSupportedCreativeFormats END,
                chcApprovalEstimateHours    = ISNULL(CAST(JSON_VALUE(@rqst, '$.approvalEstimateHours') AS INT),          tgt.chcApprovalEstimateHours),
                chcMetricsRefreshIntervalMinutes = ISNULL(CAST(JSON_VALUE(@rqst, '$.metricsRefreshIntervalMinutes') AS INT), tgt.chcMetricsRefreshIntervalMinutes),
                chcAuthMethod               = ISNULL(JSON_VALUE(@rqst, '$.authMethod'),           tgt.chcAuthMethod),
                chcKeyVaultSecretName       = ISNULL(JSON_VALUE(@rqst, '$.keyVaultSecretName'),   tgt.chcKeyVaultSecretName),
                chcStatusMappings           = CASE WHEN JSON_QUERY(@rqst, '$.statusMappings') IS NOT NULL
                                                   THEN JSON_QUERY(@rqst, '$.statusMappings')
                                                   ELSE tgt.chcStatusMappings END,
                chcSortOrder                = ISNULL(CAST(JSON_VALUE(@rqst, '$.sortOrder') AS INT), tgt.chcSortOrder),
                chcUpdatedAt                = GETUTCDATE()
        WHEN NOT MATCHED THEN
            INSERT (chcChannelType, chcDisplayName, chcDescription, chcIcon, chcColor,
                    chcEnabled, chcIsStub, chcEndpoint, chcInternalKey,
                    chcMinDailyBudget, chcMinMonthlyBudget,
                    chcSupportedObjectives, chcSupportedCreativeFormats,
                    chcApprovalEstimateHours, chcMetricsRefreshIntervalMinutes,
                    chcAuthMethod, chcKeyVaultSecretName, chcStatusMappings, chcSortOrder)
            VALUES (
                @uChannelType,
                JSON_VALUE(@rqst, '$.displayName'),
                JSON_VALUE(@rqst, '$.description'),
                JSON_VALUE(@rqst, '$.icon'),
                JSON_VALUE(@rqst, '$.color'),
                ISNULL(CAST(JSON_VALUE(@rqst, '$.enabled') AS BIT), 1),
                ISNULL(CAST(JSON_VALUE(@rqst, '$.isStub') AS BIT), 1),
                JSON_VALUE(@rqst, '$.endpoint'),
                JSON_VALUE(@rqst, '$.internalKey'),
                ISNULL(CAST(JSON_VALUE(@rqst, '$.minDailyBudget') AS DECIMAL(10,2)), 5.00),
                ISNULL(CAST(JSON_VALUE(@rqst, '$.minMonthlyBudget') AS DECIMAL(10,2)), 150.00),
                JSON_QUERY(@rqst, '$.supportedObjectives'),
                JSON_QUERY(@rqst, '$.supportedCreativeFormats'),
                ISNULL(CAST(JSON_VALUE(@rqst, '$.approvalEstimateHours') AS INT), 24),
                ISNULL(CAST(JSON_VALUE(@rqst, '$.metricsRefreshIntervalMinutes') AS INT), 60),
                JSON_VALUE(@rqst, '$.authMethod'),
                JSON_VALUE(@rqst, '$.keyVaultSecretName'),
                JSON_QUERY(@rqst, '$.statusMappings'),
                ISNULL(CAST(JSON_VALUE(@rqst, '$.sortOrder') AS INT), 0)
            );

        SET @resp = '{"ok":true}';
        RETURN;
    END

    -- ── delete: remove a channel (admin) ──
    IF @action = 'delete'
    BEGIN
        DECLARE @dChannelType VARCHAR(50) = JSON_VALUE(@rqst, '$.channelType');

        DELETE FROM dbo.tbChannelConfig WHERE chcChannelType = @dChannelType;

        SET @resp = '{"ok":true,"deleted":' + CAST(@@ROWCOUNT AS VARCHAR) + '}';
        RETURN;
    END

    SET @resp = '{"ok":false,"error":"Unknown action: ' + @action + '"}';
END
GO

-- ── Seed Data ──────────────────────────────────────────────

-- Google Ads
IF NOT EXISTS (SELECT 1 FROM dbo.tbChannelConfig WHERE chcChannelType = 'google_ads')
INSERT INTO dbo.tbChannelConfig (
    chcChannelType, chcDisplayName, chcDescription, chcIcon, chcColor,
    chcEnabled, chcIsStub, chcEndpoint,
    chcMinDailyBudget, chcMinMonthlyBudget,
    chcSupportedObjectives, chcSupportedCreativeFormats,
    chcApprovalEstimateHours, chcAuthMethod, chcKeyVaultSecretName,
    chcStatusMappings, chcSortOrder
) VALUES (
    'google_ads',
    'Google Ads',
    'Search, Display, Shopping & Performance Max across Google properties',
    'google', '#4285F4',
    1, 0, NULL,
    10.00, 300.00,
    '["awareness","traffic","conversions","leads","sales"]',
    '["text","image","responsive","video"]',
    24, 'mcc', 'google-ads-refresh-token',
    '{"ENABLED":"active","Enabled":"active","PAUSED":"paused","Paused":"paused","REMOVED":"cancelled","Removed":"cancelled","UNKNOWN":"error","UNSPECIFIED":"error"}',
    1
);

-- Meta
IF NOT EXISTS (SELECT 1 FROM dbo.tbChannelConfig WHERE chcChannelType = 'meta')
INSERT INTO dbo.tbChannelConfig (
    chcChannelType, chcDisplayName, chcDescription, chcIcon, chcColor,
    chcEnabled, chcIsStub, chcEndpoint,
    chcMinDailyBudget, chcMinMonthlyBudget,
    chcSupportedObjectives, chcSupportedCreativeFormats,
    chcApprovalEstimateHours, chcAuthMethod, chcKeyVaultSecretName,
    chcStatusMappings, chcSortOrder
) VALUES (
    'meta',
    'Meta Ads',
    'Facebook, Instagram, Messenger & Threads advertising',
    'meta', '#1877F2',
    1, 1, NULL,
    5.00, 250.00,
    '["awareness","traffic","conversions","leads","sales"]',
    '["image","video","carousel","stories"]',
    48, 'oauth2', 'meta-access-token',
    '{"ACTIVE":"active","PAUSED":"paused","DELETED":"cancelled","ARCHIVED":"completed","IN_PROCESS":"pending","WITH_ISSUES":"error","CAMPAIGN_PAUSED":"paused","ADSET_PAUSED":"paused","DISAPPROVED":"error","PREAPPROVED":"pending","PENDING_REVIEW":"pending","PENDING_BILLING_INFO":"error"}',
    2
);

-- TikTok
IF NOT EXISTS (SELECT 1 FROM dbo.tbChannelConfig WHERE chcChannelType = 'tiktok')
INSERT INTO dbo.tbChannelConfig (
    chcChannelType, chcDisplayName, chcDescription, chcIcon, chcColor,
    chcEnabled, chcIsStub, chcEndpoint,
    chcMinDailyBudget, chcMinMonthlyBudget,
    chcSupportedObjectives, chcSupportedCreativeFormats,
    chcApprovalEstimateHours, chcAuthMethod, chcKeyVaultSecretName,
    chcStatusMappings, chcSortOrder
) VALUES (
    'tiktok',
    'TikTok Ads',
    'In-feed video ads across TikTok and partner apps',
    'tiktok', '#000000',
    1, 1, NULL,
    20.00, 200.00,
    '["awareness","traffic","conversions","leads","sales"]',
    '["video","image","spark_ads"]',
    24, 'oauth2', 'tiktok-access-token',
    '{"ENABLE":"active","CAMPAIGN_STATUS_ENABLE":"active","DISABLE":"paused","CAMPAIGN_STATUS_DISABLE":"paused","DELETE":"cancelled","CAMPAIGN_STATUS_DELETE":"cancelled","BUDGET_EXCEED":"paused","CAMPAIGN_STATUS_BUDGET_EXCEED":"paused","ADVERTISER_AUDIT_DENY":"error","CAMPAIGN_STATUS_ADVERTISER_AUDIT_DENY":"error","NOT_DELETE":"active","ADVERTISER_AUDIT":"pending","CAMPAIGN_STATUS_ADVERTISER_AUDIT":"pending","REAUDIT":"pending","ALL":"active"}',
    3
);

PRINT 'Channel config seeded successfully';
GO
