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("20260305013000_SeedFinanceCostMenuAndPermissions")]
public sealed class SeedFinanceCostMenuAndPermissions : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.Sql(
            """
            DO $$
            DECLARE
                v_parent_permission_id bigint;
                v_view_permission_id bigint;
                v_manage_permission_id bigint;
                v_parent_menu_id bigint;
                v_cost_menu_id bigint;
                v_permission_seed_base bigint := 840100000000000000;
                v_menu_seed_base bigint := 850100000000000000;
            BEGIN
                -- 1. 确保财务权限分组存在。
                SELECT "Id"
                INTO v_parent_permission_id
                FROM public.permissions
                WHERE "Code" = 'group:tenant:finance'
                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:finance', '财务中心权限分组',
                        NOW(), NULL, NULL,
                        NULL, NULL, NULL,
                        0, 5000, '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:finance:cost:view', '查看成本录入与成本分析',
                    NOW(), NULL, NULL,
                    NULL, NULL, NULL,
                    v_parent_permission_id, 5110, '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:finance:cost:manage', '维护成本录入明细与保存数据',
                    NOW(), NULL, NULL,
                    NULL, NULL, NULL,
                    v_parent_permission_id, 5120, '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();

                -- 4. 回填权限 ID。
                SELECT "Id" INTO v_view_permission_id FROM public.permissions WHERE "Code" = 'tenant:finance:cost:view' LIMIT 1;
                SELECT "Id" INTO v_manage_permission_id FROM public.permissions WHERE "Code" = 'tenant:finance:cost:manage' LIMIT 1;

                -- 5. 确保租户端财务父菜单存在。
                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;

                -- 6. Upsert 成本管理菜单。
                SELECT "Id"
                INTO v_cost_menu_id
                FROM public.menu_definitions
                WHERE "Portal" = 1
                  AND ("Path" = '/finance/cost' OR ("Path" = 'cost' AND "Component" = '/finance/cost/index'))
                ORDER BY "DeletedAt" NULLS FIRST, "Id"
                LIMIT 1;

                IF v_cost_menu_id IS NULL THEN
                    v_cost_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_cost_menu_id, v_parent_menu_id, 'CostManagement', '/finance/cost', '/finance/cost/index', '成本管理', 'lucide:circle-dollar-sign',
                        FALSE, NULL, TRUE, 520,
                        'tenant:finance:cost:view', 'tenant:finance:cost:view,tenant:finance:cost:manage', '', 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" = 'CostManagement',
                        "Path" = '/finance/cost',
                        "Component" = '/finance/cost/index',
                        "Title" = '成本管理',
                        "Icon" = 'lucide:circle-dollar-sign',
                        "IsIframe" = FALSE,
                        "Link" = NULL,
                        "KeepAlive" = TRUE,
                        "SortOrder" = 520,
                        "RequiredPermissions" = 'tenant:finance:cost:view',
                        "MetaPermissions" = 'tenant:finance:cost:view,tenant:finance:cost:manage',
                        "MetaRoles" = '',
                        "DeletedAt" = NULL,
                        "DeletedBy" = NULL,
                        "UpdatedAt" = NOW(),
                        "Portal" = 1
                    WHERE "Id" = v_cost_menu_id;
                END IF;

                -- 7. 为 tenant-admin 角色授予成本权限。
                INSERT INTO public.role_permissions (
                    "Id", "RoleId", "PermissionId", "CreatedAt", "UpdatedAt", "DeletedAt",
                    "CreatedBy", "UpdatedBy", "DeletedBy", "TenantId", "Portal")
                SELECT
                    ABS(HASHTEXTEXTENDED('tenant-admin:cost:' || 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_manage_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;

                -- 8. 为 tenant-admin 角色模板授予成本权限。
                INSERT INTO public.role_template_permissions (
                    "Id", "RoleTemplateId", "PermissionCode",
                    "CreatedAt", "UpdatedAt", "DeletedAt",
                    "CreatedBy", "UpdatedBy", "DeletedBy")
                SELECT
                    ABS(HASHTEXTEXTENDED('template-cost:' || 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:finance:cost:view', 'tenant:finance:cost:manage']) 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:finance:cost:view', 'tenant:finance:cost:manage'));

                DELETE FROM public.role_template_permissions
                WHERE "PermissionCode" IN ('tenant:finance:cost:view', 'tenant:finance:cost:manage');

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

                DELETE FROM public.permissions
                WHERE "Code" IN ('tenant:finance:cost:view', 'tenant:finance:cost:manage');
            END $$;
            """);
    }
}
