using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using TakeoutSaaS.Infrastructure.Identity.Persistence;

#nullable disable

namespace TakeoutSaaS.Infrastructure.Migrations.IdentityDb;

/// <summary>
/// 写入经营报表菜单与权限定义。
/// </summary>
[DbContext(typeof(IdentityDbContext))]
[Migration("20260305093000_SeedFinanceReportMenuAndPermissions")]
public sealed class SeedFinanceReportMenuAndPermissions : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql(
            """
            DO $$
            DECLARE
                v_parent_permission_id bigint;
                v_view_permission_id bigint;
                v_export_permission_id bigint;
                v_parent_menu_id bigint;
                v_report_menu_id bigint;
                v_permission_seed_base bigint := 840200000000000000;
                v_menu_seed_base bigint := 850200000000000000;
            BEGIN
                -- 1. 确保统计权限分组存在。
                SELECT "Id"
                INTO v_parent_permission_id
                FROM public.permissions
                WHERE "Code" = 'group:tenant:statistics'
                ORDER BY "Id"
                LIMIT 1;

                IF v_parent_permission_id IS NULL THEN
                    v_parent_permission_id := v_permission_seed_base + 1;
                    INSERT INTO public.permissions (
                        "Id", "Name", "Code", "Description",
                        "CreatedAt", "UpdatedAt", "DeletedAt",
                        "CreatedBy", "UpdatedBy", "DeletedBy",
                        "ParentId", "SortOrder", "Type", "Portal")
                    VALUES (
                        v_parent_permission_id, '经营分析', 'group:tenant:statistics', '经营分析权限分组',
                        NOW(), NULL, NULL,
                        NULL, NULL, NULL,
                        0, 5300, 'group', 1)
                    ON CONFLICT ("Code") DO NOTHING;
                END IF;

                -- 2. Upsert 经营报表查看权限。
                INSERT INTO public.permissions (
                    "Id", "Name", "Code", "Description",
                    "CreatedAt", "UpdatedAt", "DeletedAt",
                    "CreatedBy", "UpdatedBy", "DeletedBy",
                    "ParentId", "SortOrder", "Type", "Portal")
                VALUES (
                    v_permission_seed_base + 11, '经营报表查看', 'tenant:statistics:report:view', '查看经营报表列表与详情',
                    NOW(), NULL, NULL,
                    NULL, NULL, NULL,
                    v_parent_permission_id, 5310, 'leaf', 1)
                ON CONFLICT ("Code") DO UPDATE
                SET "Name" = EXCLUDED."Name",
                    "Description" = EXCLUDED."Description",
                    "ParentId" = EXCLUDED."ParentId",
                    "SortOrder" = EXCLUDED."SortOrder",
                    "Type" = EXCLUDED."Type",
                    "Portal" = EXCLUDED."Portal",
                    "DeletedAt" = NULL,
                    "DeletedBy" = NULL,
                    "UpdatedAt" = NOW();

                -- 3. Upsert 经营报表导出权限。
                INSERT INTO public.permissions (
                    "Id", "Name", "Code", "Description",
                    "CreatedAt", "UpdatedAt", "DeletedAt",
                    "CreatedBy", "UpdatedBy", "DeletedBy",
                    "ParentId", "SortOrder", "Type", "Portal")
                VALUES (
                    v_permission_seed_base + 12, '经营报表导出', 'tenant:statistics:report:export', '导出经营报表 PDF / Excel / ZIP',
                    NOW(), NULL, NULL,
                    NULL, NULL, NULL,
                    v_parent_permission_id, 5320, 'leaf', 1)
                ON CONFLICT ("Code") DO UPDATE
                SET "Name" = EXCLUDED."Name",
                    "Description" = EXCLUDED."Description",
                    "ParentId" = EXCLUDED."ParentId",
                    "SortOrder" = EXCLUDED."SortOrder",
                    "Type" = EXCLUDED."Type",
                    "Portal" = EXCLUDED."Portal",
                    "DeletedAt" = NULL,
                    "DeletedBy" = NULL,
                    "UpdatedAt" = NOW();

                SELECT "Id" INTO v_view_permission_id
                FROM public.permissions
                WHERE "Code" = 'tenant:statistics:report:view'
                LIMIT 1;

                SELECT "Id" INTO v_export_permission_id
                FROM public.permissions
                WHERE "Code" = 'tenant:statistics:report:export'
                LIMIT 1;

                -- 4. 确保租户端财务父菜单存在。
                SELECT "Id"
                INTO v_parent_menu_id
                FROM public.menu_definitions
                WHERE "Portal" = 1 AND "Path" = '/finance' AND "DeletedAt" IS NULL
                ORDER BY "Id"
                LIMIT 1;

                IF v_parent_menu_id IS NULL THEN
                    v_parent_menu_id := v_menu_seed_base + 1;
                    INSERT INTO public.menu_definitions (
                        "Id", "ParentId", "Name", "Path", "Component", "Title", "Icon",
                        "IsIframe", "Link", "KeepAlive", "SortOrder",
                        "RequiredPermissions", "MetaPermissions", "MetaRoles", "AuthListJson",
                        "CreatedAt", "UpdatedAt", "DeletedAt", "CreatedBy", "UpdatedBy", "DeletedBy", "Portal")
                    VALUES (
                        v_parent_menu_id, 0, 'Finance', '/finance', 'BasicLayout', '财务中心', 'lucide:wallet',
                        FALSE, NULL, FALSE, 500,
                        '', '', '', NULL,
                        NOW(), NULL, NULL, NULL, NULL, NULL, 1)
                    ON CONFLICT ("Id") DO NOTHING;
                END IF;

                -- 5. Upsert 经营报表菜单。
                SELECT "Id"
                INTO v_report_menu_id
                FROM public.menu_definitions
                WHERE "Portal" = 1
                  AND ("Path" = '/finance/report' OR ("Path" = 'report' AND "Component" = '/finance/report/index'))
                ORDER BY "DeletedAt" NULLS FIRST, "Id"
                LIMIT 1;

                IF v_report_menu_id IS NULL THEN
                    v_report_menu_id := v_menu_seed_base + 11;
                    INSERT INTO public.menu_definitions (
                        "Id", "ParentId", "Name", "Path", "Component", "Title", "Icon",
                        "IsIframe", "Link", "KeepAlive", "SortOrder",
                        "RequiredPermissions", "MetaPermissions", "MetaRoles", "AuthListJson",
                        "CreatedAt", "UpdatedAt", "DeletedAt", "CreatedBy", "UpdatedBy", "DeletedBy", "Portal")
                    VALUES (
                        v_report_menu_id, v_parent_menu_id, 'BusinessReport', '/finance/report', '/finance/report/index', '经营报表', 'lucide:file-bar-chart-2',
                        FALSE, NULL, TRUE, 530,
                        'tenant:statistics:report:view', 'tenant:statistics:report:view,tenant:statistics:report:export', '', NULL,
                        NOW(), NULL, NULL, NULL, NULL, NULL, 1)
                    ON CONFLICT ("Id") DO NOTHING;
                ELSE
                    UPDATE public.menu_definitions
                    SET "ParentId" = v_parent_menu_id,
                        "Name" = 'BusinessReport',
                        "Path" = '/finance/report',
                        "Component" = '/finance/report/index',
                        "Title" = '经营报表',
                        "Icon" = 'lucide:file-bar-chart-2',
                        "IsIframe" = FALSE,
                        "Link" = NULL,
                        "KeepAlive" = TRUE,
                        "SortOrder" = 530,
                        "RequiredPermissions" = 'tenant:statistics:report:view',
                        "MetaPermissions" = 'tenant:statistics:report:view,tenant:statistics:report:export',
                        "MetaRoles" = '',
                        "DeletedAt" = NULL,
                        "DeletedBy" = NULL,
                        "UpdatedAt" = NOW(),
                        "Portal" = 1
                    WHERE "Id" = v_report_menu_id;
                END IF;

                -- 6. 为 tenant-admin 角色授予权限。
                INSERT INTO public.role_permissions (
                    "Id", "RoleId", "PermissionId", "CreatedAt", "UpdatedAt", "DeletedAt",
                    "CreatedBy", "UpdatedBy", "DeletedBy", "TenantId", "Portal")
                SELECT
                    ABS(HASHTEXTEXTENDED('tenant-admin:report:' || role."Id"::text || ':' || permission_id::text, 0)),
                    role."Id",
                    permission_id,
                    NOW(), NULL, NULL,
                    NULL, NULL, NULL,
                    role."TenantId",
                    1
                FROM public.roles role
                CROSS JOIN LATERAL (
                    SELECT UNNEST(ARRAY[v_view_permission_id, v_export_permission_id]) AS permission_id
                ) item
                WHERE role."Code" = 'tenant-admin'
                  AND role."DeletedAt" IS NULL
                  AND item.permission_id IS NOT NULL
                ON CONFLICT ("RoleId", "PermissionId") DO UPDATE
                SET "DeletedAt" = NULL,
                    "DeletedBy" = NULL,
                    "UpdatedAt" = NOW(),
                    "Portal" = 1;

                -- 7. 为 tenant-admin 角色模板授予权限。
                INSERT INTO public.role_template_permissions (
                    "Id", "RoleTemplateId", "PermissionCode",
                    "CreatedAt", "UpdatedAt", "DeletedAt",
                    "CreatedBy", "UpdatedBy", "DeletedBy")
                SELECT
                    ABS(HASHTEXTEXTENDED('template-report:' || template."Id"::text || ':' || item.permission_code, 0)),
                    template."Id",
                    item.permission_code,
                    NOW(), NULL, NULL,
                    NULL, NULL, NULL
                FROM public.role_templates template
                CROSS JOIN LATERAL (
                    SELECT UNNEST(ARRAY['tenant:statistics:report:view', 'tenant:statistics:report:export']) AS permission_code
                ) item
                WHERE template."TemplateCode" = 'tenant-admin'
                  AND template."DeletedAt" IS NULL
                ON CONFLICT ("RoleTemplateId", "PermissionCode") DO UPDATE
                SET "DeletedAt" = NULL,
                    "DeletedBy" = NULL,
                    "UpdatedAt" = NOW();
            END $$;
            """);
    }

    /// <inheritdoc />
    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql(
            """
            DO $$
            BEGIN
                DELETE FROM public.role_permissions
                WHERE "PermissionId" IN (
                    SELECT "Id"
                    FROM public.permissions
                    WHERE "Code" IN ('tenant:statistics:report:view', 'tenant:statistics:report:export'));

                DELETE FROM public.role_template_permissions
                WHERE "PermissionCode" IN ('tenant:statistics:report:view', 'tenant:statistics:report:export');

                DELETE FROM public.menu_definitions
                WHERE "Portal" = 1 AND "Path" = '/finance/report';

                DELETE FROM public.permissions
                WHERE "Code" IN ('tenant:statistics:report:view', 'tenant:statistics:report:export');
            END $$;
            """);
    }
}
