-- =============================================
-- Stored Procedure: GetNetworkTree
-- Description: دریافت درخت شبکه باینری با CTE recursive
-- Author: FourSat Team
-- Updated: 2026-04-30 — اضافه کردن IsNewActivation، PackageName، PackageId
--                       منطق هفته‌بندی از ActivatedAt به PackagePurchasedAt تغییر کرد
-- =============================================

CREATE OR ALTER PROCEDURE [CMS].[GetNetworkTree]
    @RootUserId BIGINT,
    @MaxDepth INT = 100,
    @IsClubActive BIT = NULL,
    @ActivationWeekDefinitionId BIGINT = NULL
AS
BEGIN
    SET NOCOUNT ON;

    -- تاریخ شروع و پایان هفته فیلتر
    DECLARE @WeekStartDate DATETIME = NULL;
    DECLARE @WeekEndDate   DATETIME = NULL;

    IF @ActivationWeekDefinitionId IS NOT NULL
    BEGIN
        SELECT @WeekStartDate = StartDate, @WeekEndDate = EndDate
        FROM [CMS].[WeekDefinitions]
        WHERE Id = @ActivationWeekDefinitionId;
    END

    -- CTE برای پیمایش درخت باینری به صورت recursive
    ;WITH NetworkTreeCTE AS (
        -- Base case: ریشه درخت
        SELECT 
            u.Id AS UserId,
            u.Mobile,
            u.FirstName,
            u.LastName,
            u.ReferralCode,
            u.LegPosition,
            u.NetworkParentId AS ParentId,
            0 AS NetworkLevel,
            u.Created AS UserCreated
        FROM [CMS].[Users] u
        WHERE u.Id = @RootUserId
          AND u.IsDeleted = 0

        UNION ALL

        -- Recursive case: فرزندان
        SELECT 
            u.Id AS UserId,
            u.Mobile,
            u.FirstName,
            u.LastName,
            u.ReferralCode,
            u.LegPosition,
            u.NetworkParentId AS ParentId,
            parent.NetworkLevel + 1 AS NetworkLevel,
            u.Created AS UserCreated
        FROM [CMS].[Users] u
        INNER JOIN NetworkTreeCTE parent ON u.NetworkParentId = parent.UserId
        WHERE u.IsDeleted = 0
          AND parent.NetworkLevel < @MaxDepth
    )
    SELECT 
        t.UserId,
        t.Mobile,
        t.FirstName,
        t.LastName,
        t.ReferralCode,
        t.LegPosition,
        t.ParentId,
        t.NetworkLevel,
        cm.ActivatedAt AS ClubActivatedAt,
        ISNULL(cm.IsActive, 0) AS IsClubActive,

        -- هفته فعال‌سازی بر اساس Cycle جاری (PackagePurchasedAt)
        wd.Id          AS ActivationWeekDefinitionId,
        wd.DisplayName AS ActivationWeekDisplayName,

        -- آیا کاربر در هفته هدف Cycle داشته؟
        CASE WHEN cc_target.UserId IS NOT NULL THEN 1 ELSE 0 END AS IsActivatedInTargetWeek,

        -- نوع فعال‌سازی: 1=جدید، 0=تمدید/خرید مجدد، NULL=بدون Cycle
        CASE
            WHEN cc_eff.CycleNumber IS NULL THEN NULL
            WHEN cc_eff.CycleNumber = 1     THEN 1
            ELSE                            0
        END AS IsNewActivation,

        -- نام پکیج موثر (هفته هدف اگر فیلتر باشد، وگرنه پکیج فعلی)
        ISNULL(p_eff.Title, '') AS PackageName,
        cc_eff.PackageId        AS PackageId,

        t.UserCreated
    FROM NetworkTreeCTE t
    LEFT JOIN [CMS].[ClubMemberships] cm ON cm.UserId = t.UserId AND cm.IsDeleted = 0

    -- Cycle جاری — برای نمایش هفته و پکیج وقتی فیلتر هفته نیست
    OUTER APPLY (
        SELECT TOP 1 CycleNumber, PackageId, PackagePurchasedAt
        FROM [CMS].[ClubMembershipCycles]
        WHERE UserId = t.UserId AND IsCurrentCycle = 1
    ) cc_current

    -- Cycle هفته هدف — برای IsActivatedInTargetWeek و نوع فعال‌سازی
    OUTER APPLY (
        SELECT TOP 1 UserId, CycleNumber, PackageId
        FROM [CMS].[ClubMembershipCycles]
        WHERE UserId = t.UserId
          AND @WeekStartDate IS NOT NULL
          AND PackagePurchasedAt >= @WeekStartDate
          AND PackagePurchasedAt <  @WeekEndDate
        ORDER BY CycleNumber ASC
    ) cc_target

    -- Cycle موثر: اگر هفته فیلتر داریم → cc_target، وگرنه → cc_current
    CROSS APPLY (
        SELECT
            CASE WHEN @WeekStartDate IS NOT NULL AND cc_target.UserId IS NOT NULL
                 THEN cc_target.CycleNumber ELSE cc_current.CycleNumber END AS CycleNumber,
            CASE WHEN @WeekStartDate IS NOT NULL AND cc_target.UserId IS NOT NULL
                 THEN cc_target.PackageId   ELSE cc_current.PackageId   END AS PackageId
    ) cc_eff

    -- پکیج موثر
    LEFT JOIN [CMS].[Packages] p_eff ON p_eff.Id = cc_eff.PackageId AND p_eff.IsDeleted = 0

    -- هفته بر اساس PackagePurchasedAt سایکل جاری
    LEFT JOIN [CMS].[WeekDefinitions] wd
        ON cc_current.PackagePurchasedAt >= wd.StartDate
       AND cc_current.PackagePurchasedAt <  wd.EndDate

    WHERE (@IsClubActive IS NULL OR ISNULL(cm.IsActive, 0) = @IsClubActive OR t.NetworkLevel = 0)
    ORDER BY t.NetworkLevel, t.ParentId, t.LegPosition
    OPTION (MAXRECURSION 0);
END
