/*
  PHASE 3 — Remaining 16 users from WrongDaya→Manual list (no manualy Tx from Phase 1/2).

  Users:
    2,7,8,9,10,11,12,13,40,41,105,106,130,162,169,176

  Already done in Phase 1+2 (22 users with manualy Tx): excluded here.

  Per user (skip if UPP already exists for that UserId):
    1) Reuse deposit Tx if WH links to Success Tx with Amount=56000000
    2) Else fix WH.RefrenceId when CreatedBy hints an existing manualy Tx
    3) Else CREATE Transaction (RefId FIX3-{UserId}) — no wallet charge
    4) Link stub WH (Ref=0) to Tx OR insert history-only WH
    5) INSERT UserPackagePurchases Manual(3)

  User 162: skipped for UPP if any UPP already exists (has UPP from ManualPayment flow).

  Does NOT change Users.PackagePurchaseMethod (Phase 4 later).

  Defaults to ROLLBACK. Uncomment COMMIT after preview.
*/

SET NOCOUNT ON;
SET XACT_ABORT ON;

BEGIN TRAN;

DECLARE @Now DATETIME2 = SYSUTCDATETIME();
DECLARE @ChargeAmount BIGINT = 56000000;

DECLARE @BasePackageId BIGINT;
DECLARE @BasePackagePrice BIGINT;

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

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

DECLARE @Phase3 TABLE (UserId BIGINT PRIMARY KEY);
INSERT INTO @Phase3 (UserId) VALUES
(2),(7),(8),(9),(10),(11),(12),(13),(40),(41),
(105),(106),(130),(162),(169),(176);

DECLARE @Phase3Count INT = (SELECT COUNT(*) FROM @Phase3);
PRINT CONCAT('Phase3 users: ', @Phase3Count);

------------------------------------------------------------
-- Preview: current ledger state
------------------------------------------------------------
SELECT
    p.UserId,
    u.Mobile,
    u.FirstName,
    u.LastName,
    u.PackagePurchaseMethod,
    (SELECT COUNT(*) FROM CMS.UserPackagePurchases upp
     WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0) AS UppCount,
    (SELECT TOP (1) upp.Id FROM CMS.UserPackagePurchases upp
     WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0 ORDER BY upp.Id DESC) AS LatestUppId,
    (SELECT COUNT(*) FROM CMS.UserWalletHistories h
     INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0
     WHERE w.UserId = p.UserId AND h.IsDeleted = 0) AS WhCount,
    (SELECT COUNT(*) FROM CMS.UserWalletHistories h
     INNER JOIN CMS.UserWallets w ON w.Id = h.WalletId AND w.IsDeleted = 0
     WHERE w.UserId = p.UserId AND h.IsDeleted = 0
       AND h.ChangeValue >= @ChargeAmount AND h.RefrenceId > 0) AS WhFullDepositCount,
    CASE
        WHEN EXISTS (
            SELECT 1 FROM CMS.UserPackagePurchases upp
            WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0
        ) THEN N'SKIP_HAS_UPP'
        ELSE N'NEEDS_UPP'
    END AS UppPlan
FROM @Phase3 p
INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0
ORDER BY p.UserId;

------------------------------------------------------------
-- Resolve Tx per user needing UPP
------------------------------------------------------------
SELECT
    p.UserId,
    u.Mobile,
    COALESCE(
        NULLIF(cm.LastPackageId, 0),
        NULLIF(cm.FirstPackageId, 0),
        @BasePackageId
    ) AS PackageId,
    COALESCE(cm.ActivatedAt, cm.Created, @Now) AS PurchasedAt,
    dep.TxId AS ExistingDepositTxId,
    dep.WhId AS ExistingDepositWhId,
    stub.StubWhId,
    stub.StubCreatedBy,
    CAST(NULL AS BIGINT) AS ResolvedTxId,
    CAST(N'' AS NVARCHAR(40)) AS TxSource,
    CAST(N'' AS NVARCHAR(40)) AS PlanAction
INTO #Plan
FROM @Phase3 p
INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0
LEFT JOIN CMS.ClubMemberships cm ON cm.UserId = p.UserId AND cm.IsDeleted = 0
OUTER APPLY (
    SELECT TOP (1)
        t.Id AS TxId,
        h.Id AS WhId
    FROM CMS.UserWallets w
    INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0
    INNER JOIN CMS.Transactions t ON t.Id = h.RefrenceId
        AND t.IsDeleted = 0 AND t.PaymentStatus = 0 AND t.Amount = @ChargeAmount
    WHERE w.UserId = p.UserId AND w.IsDeleted = 0
      AND h.ChangeValue >= @ChargeAmount
      AND h.IsIncrease = 1
    ORDER BY h.Id ASC
) dep
OUTER APPLY (
    SELECT TOP (1)
        h.Id AS StubWhId,
        h.CreatedBy AS StubCreatedBy
    FROM CMS.UserWallets w
    INNER JOIN CMS.UserWalletHistories h ON h.WalletId = w.Id AND h.IsDeleted = 0
    WHERE w.UserId = p.UserId AND w.IsDeleted = 0
      AND (h.RefrenceId IS NULL OR h.RefrenceId = 0)
    ORDER BY h.Id ASC
) stub
WHERE NOT EXISTS (
    SELECT 1 FROM CMS.UserPackagePurchases upp
    WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0
);

-- Pass 1: existing full deposit WH→Tx
UPDATE pl
SET
    ResolvedTxId = pl.ExistingDepositTxId,
    TxSource = N'WH_DEPOSIT',
    PlanAction = N'CREATE_UPP_REUSE_TX'
FROM #Plan pl
WHERE pl.ExistingDepositTxId IS NOT NULL;

-- Pass 2: stub CreatedBy → manualy Tx
UPDATE pl
SET
    ResolvedTxId = t.Id,
    TxSource = N'WH_STUB_HINT',
    PlanAction = N'FIX_STUB_LINK_UPP'
FROM #Plan pl
INNER JOIN CMS.Transactions t ON t.Id = TRY_CAST(pl.StubCreatedBy AS BIGINT)
    AND t.IsDeleted = 0 AND t.PaymentStatus = 0 AND t.RefId LIKE N'manualy%'
WHERE pl.ResolvedTxId IS NULL
  AND TRY_CAST(pl.StubCreatedBy AS BIGINT) > 0;

-- Pass 3: need new Tx
UPDATE pl
SET
    TxSource = N'CREATE_TX',
    PlanAction = N'CREATE_TX_WH_UPP'
FROM #Plan pl
WHERE pl.ResolvedTxId IS NULL;

SELECT
    UserId, Mobile, PackageId, PurchasedAt,
    ExistingDepositTxId, ExistingDepositWhId,
    StubWhId, StubCreatedBy,
    ResolvedTxId, TxSource, PlanAction
FROM #Plan
ORDER BY UserId;

DECLARE @NeedPlan INT = (SELECT COUNT(*) FROM #Plan);
PRINT CONCAT('Users needing UPP in Phase3: ', @NeedPlan);

------------------------------------------------------------
-- Execute: cursor per user
------------------------------------------------------------
DECLARE @UserId BIGINT;
DECLARE @Mobile NVARCHAR(50);
DECLARE @PackageId BIGINT;
DECLARE @PurchasedAt DATETIME2;
DECLARE @ExistingDepositTxId BIGINT;
DECLARE @StubWhId BIGINT;
DECLARE @ResolvedTxId BIGINT;
DECLARE @TxSource NVARCHAR(40);
DECLARE @TxId BIGINT;
DECLARE @WalletId BIGINT;
DECLARE @DiscountAmount BIGINT;
DECLARE @NetworkBalance BIGINT;
DECLARE @HistoryAt DATETIME2;
DECLARE @CreatedTx INT = 0;
DECLARE @CreatedUpp INT = 0;
DECLARE @CreatedWh INT = 0;
DECLARE @FixedWh INT = 0;

DECLARE cur CURSOR LOCAL FAST_FORWARD FOR
    SELECT UserId, Mobile, PackageId, PurchasedAt,
           ExistingDepositTxId, StubWhId, ResolvedTxId, TxSource
    FROM #Plan;

OPEN cur;
FETCH NEXT FROM cur INTO
    @UserId, @Mobile, @PackageId, @PurchasedAt,
    @ExistingDepositTxId, @StubWhId, @ResolvedTxId, @TxSource;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @TxId = @ResolvedTxId;

    IF @TxId IS NULL
    BEGIN
        INSERT INTO CMS.Transactions
        (
            Amount, Description, PaymentStatus, PaymentDate, RefId, Type,
            Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
        )
        VALUES
        (
            @ChargeAmount,
            N'عضویت دستی باشگاه مشتریان - backfill Phase3 WrongDaya',
            0,
            @PurchasedAt,
            CONCAT(N'FIX3-', @UserId),
            2,
            @PurchasedAt,
            @Mobile,
            @PurchasedAt,
            @Mobile,
            0
        );
        SET @TxId = SCOPE_IDENTITY();
        SET @CreatedTx = @CreatedTx + 1;
    END

    IF @StubWhId IS NOT NULL
       AND EXISTS (
           SELECT 1 FROM CMS.UserWalletHistories h
           WHERE h.Id = @StubWhId AND h.IsDeleted = 0
             AND (h.RefrenceId IS NULL OR h.RefrenceId = 0)
       )
    BEGIN
        UPDATE CMS.UserWalletHistories
        SET RefrenceId = @TxId, LastModified = @Now
        WHERE Id = @StubWhId;
        SET @FixedWh = @FixedWh + @@ROWCOUNT;
    END

    SELECT @WalletId = w.Id, @NetworkBalance = COALESCE(w.NetworkBalance, 0)
    FROM CMS.UserWallets w
    WHERE w.UserId = @UserId AND w.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, @PurchasedAt, @PurchasedAt, 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
        SELECT
            @HistoryAt = COALESCE(t.PaymentDate, @PurchasedAt),
            @DiscountAmount = CAST(ROUND(@ChargeAmount * COALESCE(pkg.DiscountMultiplier, 2.0), 0) AS BIGINT)
        FROM CMS.Transactions t
        LEFT JOIN CMS.Packages pkg ON pkg.Id = @PackageId AND pkg.IsDeleted = 0
        WHERE t.Id = @TxId;

        INSERT INTO CMS.UserWalletHistories
        (
            WalletId, CurrentBalance, ChangeValue, CurrentNetworkBalance, ChangeNerworkValue,
            CurrentDiscountBalance, ChangeDiscountValue, IsIncrease, RefrenceId, PackageId,
            Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
        )
        VALUES
        (
            @WalletId, 0, @ChargeAmount, @NetworkBalance, 0,
            0, @DiscountAmount, 1, @TxId, @PackageId,
            @HistoryAt, NULL, @HistoryAt, NULL, 0
        );
        SET @CreatedWh = @CreatedWh + 1;
    END

    IF NOT EXISTS (
        SELECT 1 FROM CMS.UserPackagePurchases upp
        WHERE upp.UserId = @UserId AND upp.IsDeleted = 0 AND upp.TransactionId = @TxId
    )
    BEGIN
        INSERT INTO CMS.UserPackagePurchases
        (
            UserId, PackageId, PurchaseMethod, PurchasedAt, Amount,
            OrderId, TransactionId, Created, CreatedBy, LastModified, LastModifiedBy, IsDeleted
        )
        VALUES
        (
            @UserId, @PackageId, 3,
            @PurchasedAt, @ChargeAmount,
            NULL, @TxId, @Now, NULL, @Now, NULL, 0
        );
        SET @CreatedUpp = @CreatedUpp + 1;
    END

    FETCH NEXT FROM cur INTO
        @UserId, @Mobile, @PackageId, @PurchasedAt,
        @ExistingDepositTxId, @StubWhId, @ResolvedTxId, @TxSource;
END

CLOSE cur;
DEALLOCATE cur;
DROP TABLE #Plan;

PRINT CONCAT('Tx created: ', @CreatedTx,
             ' | WH Ref fixed: ', @FixedWh,
             ' | WH created: ', @CreatedWh,
             ' | UPP created: ', @CreatedUpp);

------------------------------------------------------------
-- Verify all 16 have UPP
------------------------------------------------------------
SELECT
    p.UserId,
    u.Mobile,
    CASE WHEN upp.UppId IS NOT NULL THEN N'OK' ELSE N'MISSING_UPP' END AS UppStatus,
    upp.UppId,
    upp.PurchaseMethod,
    upp.TransactionId AS UppTxId,
    t.RefId AS TxRefId
FROM @Phase3 p
INNER JOIN CMS.Users u ON u.Id = p.UserId AND u.IsDeleted = 0
OUTER APPLY (
    SELECT TOP (1)
        upp2.Id AS UppId,
        upp2.PurchaseMethod,
        upp2.TransactionId
    FROM CMS.UserPackagePurchases upp2
    WHERE upp2.UserId = p.UserId AND upp2.IsDeleted = 0
    ORDER BY upp2.Id DESC
) upp
LEFT JOIN CMS.Transactions t ON t.Id = upp.TransactionId
ORDER BY p.UserId;

SELECT N'Phase3 users still without UPP' AS CheckName, COUNT(*) AS Cnt
FROM @Phase3 p
WHERE NOT EXISTS (
    SELECT 1 FROM CMS.UserPackagePurchases upp
    WHERE upp.UserId = p.UserId AND upp.IsDeleted = 0
);

ROLLBACK;
-- COMMIT;

PRINT 'Done (rolled back by default). Uncomment COMMIT when preview looks correct.';
