/*
  Staging fix: complete post-Daya processing for Excel rows with status «فعال شده»
  that are NOT_PROCESSED or PARTIAL.

  Classification:
    DONE          — credit + processed + Daya UPP
    PARTIAL       — HasReceivedDayaCredit OR IsProcessed OR existing «اعتبار دایا» Tx in wallet
    NOT_PROCESSED — none of the above (will create Tx + ledger WH)

  If ExistingDayaTxId found (wallet RefrenceId → Tx Description LIKE '%اعتبار دایا%'
  OR Tx.RefId = ContractNumber): REUSE that Tx — do NOT create Transaction.

  NO wallet Balance/DiscountBalance charge — UserWalletHistory is ledger-only when needed.

  Special UserId mapping (shared NationalCode):
    C4_D8815963 / 2490371436 → UserId 50
    C4_G8945289 / 2490371436 → UserId 51

  @Commit = 0 → dry-run (ROLLBACK)
  @Commit = 1 → apply
*/

SET NOCOUNT ON;
SET XACT_ABORT ON;

DECLARE @Commit BIT = 0; -- << set 1 to apply

DECLARE @Now DATETIME2 = SYSUTCDATETIME();
DECLARE @PackageId BIGINT;
DECLARE @PackagePrice BIGINT;
DECLARE @DiscountMultiplier DECIMAL(18,4);
DECLARE @DiscountAmount BIGINT;

SELECT TOP (1)
    @PackageId = Id,
    @PackagePrice = Price,
    @DiscountMultiplier = DiscountMultiplier
FROM CMS.Packages
WHERE IsDeleted = 0 AND IsBasePackage = 1
ORDER BY Id;

IF @PackageId IS NULL
    THROW 50001, 'Base package not found.', 1;

SET @DiscountAmount = CAST(@PackagePrice * @DiscountMultiplier AS BIGINT);

PRINT CONCAT('PackageId=', @PackageId, ' Price=', @PackagePrice, ' Discount=', @DiscountAmount);

------------------------------------------------------------
-- Targets: Excel «فعال شده»
------------------------------------------------------------
DECLARE @Targets TABLE (
    ContractNumber NVARCHAR(50) NOT NULL,
    NationalCode   NVARCHAR(20) NOT NULL,
    UserIdHint     BIGINT NULL  -- explicit override when NC is shared
);

INSERT INTO @Targets (ContractNumber, NationalCode, UserIdHint) VALUES
(N'C4_H10706299', N'4060667961', NULL),
(N'C4_P9320383',  N'2572729636', NULL),
(N'C4_Q9465813',  N'2480017796', NULL),
(N'C4_B9348378',  N'0452314488', NULL),
(N'C4_X9630520',  N'0680164286', NULL),
(N'C4_B9813553',  N'0055680364', NULL), -- may match DayaLoanContracts.NationalCode if Users.NC differs
(N'C4_M9994735',  N'0793851572', NULL),
(N'C4_S9301452',  N'0082242925', NULL),
(N'C4_T9961063',  N'0312342993', NULL),
(N'C4_L9524515',  N'0024757489', NULL),
(N'C4_Q9947535',  N'2480259668', NULL),
(N'C4_T9892089',  N'2451477016', NULL),
(N'C4_W8785358',  N'0322922720', NULL),
(N'C4_D8815963',  N'2490371436', 50),  -- earlier activation → user 50
(N'C4_G8945289',  N'2490371436', 51),  -- later activation → user 51
(N'C4_J8388494',  N'2002637903', NULL);

DECLARE @Work TABLE (
    ContractNumber NVARCHAR(50),
    NationalCode NVARCHAR(20),
    UserId BIGINT,
    DayaContractId BIGINT NULL,
    HasCredit BIT,
    IsProcessed BIT,
    HasDayaUpp BIT,
    ExistingDayaTxId BIGINT NULL, -- Tx از قبل با شرح «اعتبار دایا» / RefId قرارداد (شارژ شده)
    Verdict NVARCHAR(20)
);

INSERT INTO @Work (ContractNumber, NationalCode, UserId, DayaContractId, HasCredit, IsProcessed, HasDayaUpp, ExistingDayaTxId, Verdict)
SELECT
    t.ContractNumber,
    t.NationalCode,
    u.Id,
    d.Id,
    CAST(ISNULL(u.HasReceivedDayaCredit, 0) AS BIT),
    CAST(ISNULL(d.IsProcessed, 0) AS BIT),
    CAST(CASE WHEN EXISTS (
        SELECT 1
        FROM CMS.UserPackagePurchases upp
        LEFT JOIN CMS.Transactions tx ON tx.Id = upp.TransactionId AND tx.IsDeleted = 0
        WHERE upp.UserId = u.Id
          AND upp.IsDeleted = 0
          AND upp.PurchaseMethod = 1
          AND (upp.TransactionId IS NULL OR tx.PaymentStatus = 0)
    ) THEN 1 ELSE 0 END AS BIT),
    etx.TxId,
    CASE
        WHEN u.Id IS NULL THEN N'NO_USER'
        WHEN ISNULL(u.HasReceivedDayaCredit, 0) = 1
         AND ISNULL(d.IsProcessed, 0) = 1
         AND EXISTS (
            SELECT 1
            FROM CMS.UserPackagePurchases upp
            LEFT JOIN CMS.Transactions tx ON tx.Id = upp.TransactionId AND tx.IsDeleted = 0
            WHERE upp.UserId = u.Id
              AND upp.IsDeleted = 0
              AND upp.PurchaseMethod = 1
              AND (upp.TransactionId IS NULL OR tx.PaymentStatus = 0)
         ) THEN N'DONE'
        -- قبلاً شارژ دایا در کیف/تراکنش هست ولی فلگ/UPP/قرارداد کامل نیست
        WHEN etx.TxId IS NOT NULL THEN N'PARTIAL'
        WHEN ISNULL(u.HasReceivedDayaCredit, 0) = 1
          OR ISNULL(d.IsProcessed, 0) = 1 THEN N'PARTIAL'
        ELSE N'NOT_PROCESSED'
    END
FROM @Targets t
OUTER APPLY (
    SELECT TOP (1) u0.*
    FROM CMS.Users u0
    WHERE u0.IsDeleted = 0
      AND (
            (t.UserIdHint IS NOT NULL AND u0.Id = t.UserIdHint)
         OR (t.UserIdHint IS NULL AND u0.NationalCode = t.NationalCode)
         OR (t.UserIdHint IS NULL AND EXISTS (
                SELECT 1 FROM CMS.DayaLoanContracts dx
                WHERE dx.UserId = u0.Id
                  AND dx.NationalCode = t.NationalCode
                  AND dx.IsDeleted = 0
            ))
      )
    ORDER BY
        CASE WHEN t.UserIdHint IS NOT NULL AND u0.Id = t.UserIdHint THEN 0 ELSE 1 END,
        CASE WHEN u0.NationalCode = t.NationalCode THEN 0 ELSE 1 END,
        u0.Id
) u
OUTER APPLY (
    SELECT TOP (1) d0.*
    FROM CMS.DayaLoanContracts d0
    WHERE d0.UserId = u.Id
      AND (
            d0.ContractNumber = t.ContractNumber
         OR d0.NationalCode = t.NationalCode
         OR d0.IsDeleted IN (0, 1)
      )
    ORDER BY
        CASE WHEN d0.ContractNumber = t.ContractNumber THEN 0 ELSE 1 END,
        CASE WHEN d0.IsDeleted = 0 THEN 0 ELSE 1 END,
        d0.Id DESC
) d
OUTER APPLY (
    -- تراکنش دایا که از قبل شارژ شده (مرجع کیف پول یا RefId قرارداد)
    SELECT TOP (1) t0.Id AS TxId
    FROM CMS.Transactions t0
    WHERE t0.IsDeleted = 0
      AND t0.PaymentStatus = 0
      AND (
            t0.RefId = t.ContractNumber
         OR (
                t0.Description LIKE N'%اعتبار دایا%'
            AND EXISTS (
                SELECT 1
                FROM CMS.UserWallets w
                INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id
                WHERE w.UserId = u.Id
                  AND h.RefrenceId = t0.Id
            )
         )
      )
    ORDER BY
        CASE WHEN t0.RefId = t.ContractNumber THEN 0 ELSE 1 END,
        t0.Id DESC
) etx;

PRINT '=== Before ===';
SELECT Verdict, COUNT(*) AS Cnt FROM @Work GROUP BY Verdict;
SELECT ContractNumber, NationalCode, UserId, DayaContractId, HasCredit, IsProcessed, HasDayaUpp,
       ExistingDayaTxId, Verdict
FROM @Work
ORDER BY Verdict, ContractNumber;

------------------------------------------------------------
-- PREVIEW: ledger actions (no wallet charge)
------------------------------------------------------------
PRINT '=== LEDGER PREVIEW (Tx + WH history-only — NO wallet charge) ===';

SELECT
    w.ContractNumber,
    w.NationalCode,
    w.UserId,
    w.Verdict,
    w.HasCredit,
    w.ExistingDayaTxId,
    CASE
        WHEN w.UserId IS NULL THEN N'SKIP_NO_USER'
        WHEN w.ExistingDayaTxId IS NOT NULL THEN N'REUSE_TX_ENSURE_WH_UPP'
        WHEN w.HasCredit = 0 THEN N'CREATE_TX_WH_UPP'
        ELSE N'SET_FLAGS_ONLY_UPP'
    END AS LedgerAction
FROM @Work w
WHERE w.Verdict IN (N'NOT_PROCESSED', N'PARTIAL')
ORDER BY LedgerAction, w.ContractNumber;

SELECT
    CASE
        WHEN w.UserId IS NULL THEN N'SKIP_NO_USER'
        WHEN w.ExistingDayaTxId IS NOT NULL THEN N'REUSE_TX_ENSURE_WH_UPP'
        WHEN w.HasCredit = 0 THEN N'CREATE_TX_WH_UPP'
        ELSE N'SET_FLAGS_ONLY_UPP'
    END AS LedgerAction,
    COUNT(*) AS Cnt
FROM @Work w
WHERE w.Verdict IN (N'NOT_PROCESSED', N'PARTIAL')
GROUP BY
    CASE
        WHEN w.UserId IS NULL THEN N'SKIP_NO_USER'
        WHEN w.ExistingDayaTxId IS NOT NULL THEN N'REUSE_TX_ENSURE_WH_UPP'
        WHEN w.HasCredit = 0 THEN N'CREATE_TX_WH_UPP'
        ELSE N'SET_FLAGS_ONLY_UPP'
    END
ORDER BY LedgerAction;

DECLARE @PreviewCreateTxCount INT = (
    SELECT COUNT(*)
    FROM @Work w
    WHERE w.Verdict IN (N'NOT_PROCESSED', N'PARTIAL')
      AND w.UserId IS NOT NULL
      AND w.ExistingDayaTxId IS NULL
      AND w.HasCredit = 0
);
PRINT CONCAT('>>> CREATE_TX (no wallet charge) count = ', @PreviewCreateTxCount);

BEGIN TRAN;

DECLARE @ContractNumber NVARCHAR(50), @NationalCode NVARCHAR(20), @UserId BIGINT;
DECLARE @DayaContractId BIGINT, @HasCredit BIT, @IsProcessed BIT, @HasDayaUpp BIT, @Verdict NVARCHAR(20);
DECLARE @ExistingDayaTxId BIGINT;
DECLARE @TxId BIGINT, @WalletId BIGINT, @NetworkBalance BIGINT, @Action NVARCHAR(200);

DECLARE @CreateTxCount INT = 0;
DECLARE @ReuseCount INT = 0;
DECLARE @SkipFlagsOnlyCount INT = 0;
DECLARE @WhCreatedCount INT = 0;

DECLARE @Log TABLE (
    ContractNumber NVARCHAR(50),
    UserId BIGINT,
    VerdictBefore NVARCHAR(20),
    ActionTaken NVARCHAR(200),
    TxId BIGINT NULL
);

DECLARE cur CURSOR LOCAL FAST_FORWARD FOR
    SELECT ContractNumber, NationalCode, UserId, DayaContractId, HasCredit, IsProcessed, HasDayaUpp, ExistingDayaTxId, Verdict
    FROM @Work
    WHERE Verdict IN (N'NOT_PROCESSED', N'PARTIAL');

OPEN cur;
FETCH NEXT FROM cur INTO @ContractNumber, @NationalCode, @UserId, @DayaContractId, @HasCredit, @IsProcessed, @HasDayaUpp, @ExistingDayaTxId, @Verdict;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @TxId = NULL;
    SET @Action = N'';

    IF @UserId IS NULL
    BEGIN
        INSERT INTO @Log VALUES (@ContractNumber, NULL, @Verdict, N'SKIP NO_USER', NULL);
        GOTO NextRow;
    END

    ------------------------------------------------------------
    -- Ensure / revive DayaLoanContract
    ------------------------------------------------------------
    IF @DayaContractId IS NULL
    BEGIN
        INSERT INTO CMS.DayaLoanContracts
        (
            UserId, NationalCode, ContractNumber, Status, IsProcessed,
            LastCheckDate, ProcessedDate, TransactionId,
            Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
        )
        VALUES
        (
            @UserId, @NationalCode, @ContractNumber, 2, 0,
            @Now, NULL, NULL,
            @Now, NULL, @Now, NULL, 0
        );
        SET @DayaContractId = SCOPE_IDENTITY();
        SET @Action = @Action + N'INSERT_CONTRACT;';
    END
    ELSE
    BEGIN
        UPDATE CMS.DayaLoanContracts
        SET
            IsDeleted = 0,
            NationalCode = @NationalCode,
            ContractNumber = @ContractNumber,
            Status = 2, -- Received («فعال شده»)
            LastCheckDate = @Now,
            LastModified = @Now
        WHERE Id = @DayaContractId;
        SET @Action = @Action + N'UPDATE_CONTRACT;';
    END

    ------------------------------------------------------------
    -- Resolve Tx (reuse existing or create ledger Tx — NO wallet charge)
    ------------------------------------------------------------
    IF @ExistingDayaTxId IS NOT NULL
    BEGIN
        SET @TxId = @ExistingDayaTxId;
        SET @Action = @Action + CONCAT(N'REUSE_EXISTING_DAYA_TX=', @TxId, N';');
        SET @ReuseCount = @ReuseCount + 1;

        UPDATE CMS.Users
        SET
            PackagePurchaseMethod = 1,
            HasReceivedDayaCredit = 1,
            DayaCreditReceivedAt = COALESCE(DayaCreditReceivedAt, @Now),
            LastModified = @Now
        WHERE Id = @UserId;

        SET @HasCredit = 1;
        SET @Action = @Action + N'SET_USER_FLAGS;';
    END
    ELSE IF @HasCredit = 0
    BEGIN
        INSERT INTO CMS.Transactions
        (
            Amount, Description, PaymentStatus, PaymentDate, RefId, Type,
            Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
        )
        VALUES
        (
            @PackagePrice,
            CONCAT(N'دریافت اعتبار دایا - قرارداد ', @ContractNumber),
            0,
            @Now,
            @ContractNumber,
            2,
            @Now, NULL, @Now, NULL, 0
        );
        SET @TxId = SCOPE_IDENTITY();
        SET @CreateTxCount = @CreateTxCount + 1;

        UPDATE CMS.Users
        SET
            HasReceivedDayaCredit = 1,
            DayaCreditReceivedAt = @Now,
            PackagePurchaseMethod = 1,
            LastModified = @Now
        WHERE Id = @UserId;

        SET @HasCredit = 1;
        SET @Action = @Action + N'CREATE_TX+USER_FLAGS;';
    END
    ELSE
    BEGIN
        UPDATE CMS.Users
        SET
            PackagePurchaseMethod = 1,
            HasReceivedDayaCredit = 1,
            DayaCreditReceivedAt = COALESCE(DayaCreditReceivedAt, @Now),
            LastModified = @Now
        WHERE Id = @UserId;
        SET @SkipFlagsOnlyCount = @SkipFlagsOnlyCount + 1;
        SET @Action = @Action + N'SET_FLAGS_ONLY;';
    END

    ------------------------------------------------------------
    -- UserWalletHistory for Tx (ledger-only — NO Balance/Discount charge)
    ------------------------------------------------------------
    IF @TxId IS NOT NULL
    BEGIN
        SELECT @WalletId = Id, @NetworkBalance = COALESCE(NetworkBalance, 0)
        FROM CMS.UserWallets
        WHERE UserId = @UserId AND IsDeleted = 0;

        IF @WalletId IS NULL
        BEGIN
            INSERT INTO CMS.UserWallets
                (UserId, Balance, NetworkBalance, DiscountBalance, WalletMode, Created, LastModified, IsDeleted)
            VALUES (@UserId, 0, 0, 0, 0, @Now, @Now, 0);
            SET @WalletId = SCOPE_IDENTITY();
            SET @NetworkBalance = 0;
        END

        IF NOT EXISTS (
            SELECT 1
            FROM CMS.UserWalletHistories h
            WHERE h.WalletId = @WalletId
              AND h.IsDeleted = 0
              AND h.RefrenceId = @TxId
        )
        BEGIN
            INSERT INTO CMS.UserWalletHistories
            (
                WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue,
                CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId,
                Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
            )
            VALUES
            (
                @WalletId, 0, @PackagePrice, @NetworkBalance, 0,
                0, @DiscountAmount, 1, @TxId, @PackageId,
                @Now, NULL, @Now, NULL, 0
            );
            SET @WhCreatedCount = @WhCreatedCount + 1;
            SET @Action = @Action + N'INSERT_WH_HISTORY;';
        END
    END

    ------------------------------------------------------------
    -- Ensure successful Daya UPP (no duplicate if already exists)
    ------------------------------------------------------------
    IF @HasDayaUpp = 0
    BEGIN
        IF @TxId IS NULL
        BEGIN
            -- فقط لجر؛ بدون شارژ کیف (نباید برای کسی که Tx دایا دارد به اینجا برسد)
            INSERT INTO CMS.Transactions
            (
                Amount, Description, PaymentStatus, PaymentDate, RefId, Type,
                Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
            )
            VALUES
            (
                @PackagePrice,
                CONCAT(N'لجر UPP دایا (بدون شارژ مجدد) - قرارداد ', @ContractNumber),
                0,
                @Now,
                CONCAT(N'UPP-DAYA-FIX-', @ContractNumber),
                2,
                @Now, NULL, @Now, NULL, 0
            );
            SET @TxId = SCOPE_IDENTITY();
            SET @Action = @Action + N'LEDGER_TX;';
        END

        INSERT INTO CMS.UserPackagePurchases
        (
            UserId, PackageId, PurchaseMethod, PurchasedAt, Amount,
            OrderId, TransactionId, Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
        )
        VALUES
        (
            @UserId, @PackageId, 1, @Now, @PackagePrice,
            NULL, @TxId, @Now, NULL, @Now, NULL, 0
        );
        SET @Action = @Action + N'INSERT_UPP;';
    END

    ------------------------------------------------------------
    -- Mark contract processed
    ------------------------------------------------------------
    UPDATE CMS.DayaLoanContracts
    SET
        IsProcessed = 1,
        ProcessedDate = COALESCE(ProcessedDate, @Now),
        TransactionId = COALESCE(TransactionId, @TxId),
        Status = 2,
        ContractNumber = @ContractNumber,
        IsDeleted = 0,
        LastModified = @Now
    WHERE Id = @DayaContractId;

    SET @Action = @Action + N'MARK_PROCESSED;';

    INSERT INTO @Log VALUES (@ContractNumber, @UserId, @Verdict, @Action, @TxId);

NextRow:
    FETCH NEXT FROM cur INTO @ContractNumber, @NationalCode, @UserId, @DayaContractId, @HasCredit, @IsProcessed, @HasDayaUpp, @ExistingDayaTxId, @Verdict;
END

CLOSE cur;
DEALLOCATE cur;

PRINT '=== LEDGER SUMMARY (no wallet charge) ===';
PRINT CONCAT('CREATE_TX count = ', @CreateTxCount);
PRINT CONCAT('REUSE_TX count = ', @ReuseCount);
PRINT CONCAT('SET_FLAGS_ONLY count = ', @SkipFlagsOnlyCount);
PRINT CONCAT('WH history created = ', @WhCreatedCount);

PRINT '=== Actions ===';
SELECT * FROM @Log ORDER BY VerdictBefore, ContractNumber;

-- Re-score after changes
PRINT '=== After (same targets) ===';
SELECT
    t.ContractNumber,
    t.NationalCode,
    u.Id AS UserId,
    u.HasReceivedDayaCredit,
    d.IsProcessed,
    d.ContractNumber AS DbContractNumber,
    d.Status,
    CASE WHEN EXISTS (
        SELECT 1 FROM CMS.UserPackagePurchases upp
        LEFT JOIN CMS.Transactions tx ON tx.Id = upp.TransactionId AND tx.IsDeleted = 0
        WHERE upp.UserId = u.Id AND upp.IsDeleted = 0 AND upp.PurchaseMethod = 1
          AND (upp.TransactionId IS NULL OR tx.PaymentStatus = 0)
    ) THEN 1 ELSE 0 END AS HasDayaUpp,
    CASE
        WHEN u.Id IS NULL THEN N'NO_USER'
        WHEN u.HasReceivedDayaCredit = 1 AND d.IsProcessed = 1
         AND EXISTS (
            SELECT 1 FROM CMS.UserPackagePurchases upp
            LEFT JOIN CMS.Transactions tx ON tx.Id = upp.TransactionId AND tx.IsDeleted = 0
            WHERE upp.UserId = u.Id AND upp.IsDeleted = 0 AND upp.PurchaseMethod = 1
              AND (upp.TransactionId IS NULL OR tx.PaymentStatus = 0)
         ) THEN N'DONE'
        WHEN u.HasReceivedDayaCredit = 1 OR d.IsProcessed = 1 THEN N'PARTIAL'
        ELSE N'NOT_PROCESSED'
    END AS Verdict
FROM @Targets t
LEFT JOIN CMS.Users u ON u.IsDeleted = 0 AND (
    (t.UserIdHint IS NOT NULL AND u.Id = t.UserIdHint) OR (t.UserIdHint IS NULL AND u.NationalCode = t.NationalCode)
)
LEFT JOIN CMS.DayaLoanContracts d ON d.IsDeleted = 0 AND d.UserId = u.Id
  AND (d.ContractNumber = t.ContractNumber OR d.NationalCode = t.NationalCode)
ORDER BY Verdict, t.ContractNumber;

IF @Commit = 1
BEGIN
    COMMIT;
    PRINT 'COMMITTED.';
END
ELSE
BEGIN
    ROLLBACK;
    PRINT 'Dry-run ROLLBACK. Set @Commit = 1 to apply.';
END
