<?php

use think\migration\Migrator;

class SeedVccPaymentData extends Migrator
{
    public function up(): void
    {
        $now = time();
        $db  = $this->getAdapter()->getConnection();

        // 动态查找财务管理菜单节点 ID
        $financeMenu = $db->query("SELECT id FROM `oa_admin_rule` WHERE title='财务管理' AND module='finance' AND pid=0 LIMIT 1")
                          ->fetchAll(\PDO::FETCH_ASSOC);
        if (empty($financeMenu)) {
            throw new \RuntimeException('找不到财务管理菜单节点，请确认基础数据已安装');
        }
        $financePid = $financeMenu[0]['id'];

        // 动态查找审批流程财务模块 ID（oa_flow_module.title='财务'）
        $flowModule = $db->query("SELECT id FROM `oa_flow_module` WHERE title='财务' LIMIT 1")
                         ->fetchAll(\PDO::FETCH_ASSOC);
        if (empty($flowModule)) {
            throw new \RuntimeException('找不到审批流程财务模块，请确认基础数据已安装');
        }
        $flowModuleId = $flowModule[0]['id'];

        // 动态查找超级权限角色 ID
        $superGroup = $db->query("SELECT id FROM `oa_admin_group` WHERE title='超级权限角色' LIMIT 1")
                         ->fetchAll(\PDO::FETCH_ASSOC);
        if (empty($superGroup)) {
            throw new \RuntimeException('找不到超级权限角色，请确认基础数据已安装');
        }
        $superGroupId = $superGroup[0]['id'];

        // 1. 注册审批类型
        $this->execute("INSERT INTO `oa_flow_cate`
            (`title`, `name`, `module_id`, `check_table`, `icon`,
             `department_ids`, `sort`, `is_copy`, `is_file`, `is_export`, `is_back`, `is_reversed`,
             `form`, `add_url`, `view_url`, `form_id`, `is_list`, `status`,
             `template_id`, `create_time`, `update_time`)
            VALUES
            ('VCC返点/提成付款申请', 'vcc_payment', {$flowModuleId}, 'vcc_payment', 'icon-fukuanshenqing',
             '', 52, 1, 1, 0, 1, 0,
             1, '/finance/vccpayment/add', '/finance/vccpayment/view', 0, 1, 1,
             0, {$now}, 0)");

        $cateId = $db->lastInsertId();

        // 2. 创建默认审批流程（自由审批流）
        $this->execute("INSERT INTO `oa_flow`
            (`title`, `cate_id`, `check_type`, `department_ids`, `copy_uids`, `flow_list`,
             `status`, `remark`, `admin_id`, `create_time`)
            VALUES
            ('VCC返点/提成付款申请审批', {$cateId}, 1, '', '', '', 1, '', 1, {$now})");

        // 3. 注册消息模板
        $this->execute("INSERT INTO `oa_template`
            (`title`, `name`, `types`, `check_types`, `remark`, `msg_link`,
             `msg_title_0`, `msg_content_0`,
             `msg_title_1`, `msg_content_1`,
             `msg_title_2`, `msg_content_2`,
             `msg_title_3`, `msg_content_3`,
             `email_link`, `status`, `admin_id`, `create_time`, `update_time`)
            VALUES
            ('VCC返点/提成付款申请审批', 'vcc_payment', 2, 0, '', '/finance/vccpayment/view/id/{action_id}',
             '{from_user}提交了一个『VCC返点/提成付款申请』，请及时审批',
             '您有一个新的『VCC返点/提成付款申请』需要处理。',
             '您提交的『VCC返点/提成付款申请』已被审批通过。',
             '您在{create_time}提交的『VCC返点/提成付款申请』已于{date}被审批通过。',
             '您提交的『VCC返点/提成付款申请』已被驳回拒绝。',
             '您在{create_time}提交的『VCC返点/提成付款申请』已于{date}被驳回拒绝。',
             '{from_user}提交的『VCC返点/提成付款申请』已被审批通过并抄送给你',
             '{from_user}在{create_time}提交的『VCC返点/提成付款申请』已被审批通过并抄送给你，请及时查看详情。',
             '', 1, 1, {$now}, 0)");

        $tplId = $db->lastInsertId();
        $this->execute("UPDATE `oa_flow_cate` SET `template_id` = {$tplId} WHERE `id` = {$cateId}");

        // 4. 菜单 + 权限节点
        $this->execute("INSERT INTO `oa_admin_rule`
            (`pid`, `src`, `title`, `name`, `module`, `icon`, `menu`, `sort`, `status`, `create_time`)
            VALUES
            ({$financePid}, 'finance/vccpayment/datalist', 'VCC返点/提成付款申请', 'VCC返点/提成付款申请', 'finance', 'icon-fukuanshenqing', 1, 52, 1, {$now})");

        $ruleId = $db->lastInsertId();

        $this->execute("INSERT INTO `oa_admin_rule`
            (`pid`, `src`, `title`, `name`, `module`, `icon`, `menu`, `sort`, `status`, `create_time`)
            VALUES
            ({$ruleId}, 'finance/vccpayment/datalist', '列表',      'VCC付款申请-列表',     'finance', '', 2, 1, 1, {$now}),
            ({$ruleId}, 'finance/vccpayment/add',      '添加/编辑', 'VCC付款申请-添加编辑', 'finance', '', 2, 2, 1, {$now}),
            ({$ruleId}, 'finance/vccpayment/view',     '详情',      'VCC付款申请-详情',     'finance', '', 2, 3, 1, {$now}),
            ({$ruleId}, 'finance/vccpayment/del',      '删除',      'VCC付款申请-删除',     'finance', '', 2, 4, 1, {$now})");

        // 5. 授权给超级权限角色
        $this->execute("UPDATE `oa_admin_group`
            SET `rules` = CONCAT(`rules`, ',', (
                SELECT GROUP_CONCAT(t.id) FROM (
                    SELECT id FROM `oa_admin_rule` WHERE id = {$ruleId} OR pid = {$ruleId}
                ) t
            ))
            WHERE `id` = {$superGroupId}");
    }

    public function down(): void
    {
        $db = $this->getAdapter()->getConnection();

        // 1. 回收权限节点：先从超级权限角色 rules 中剔除，再删除节点
        $ruleIds = $db->query("SELECT id FROM `oa_admin_rule` WHERE src LIKE 'finance/vccpayment/%'")
                      ->fetchAll(\PDO::FETCH_COLUMN);
        if (!empty($ruleIds)) {
            $this->removeRulesFromGroups($ruleIds);
            $in = implode(',', array_map('intval', $ruleIds));
            $this->execute("DELETE FROM `oa_admin_rule` WHERE id IN ({$in})");
        }

        // 2. 删除审批流程（依赖审批类型 cate_id，需先删）
        $cateIds = $db->query("SELECT id FROM `oa_flow_cate` WHERE name='vcc_payment'")
                      ->fetchAll(\PDO::FETCH_COLUMN);
        if (!empty($cateIds)) {
            $in = implode(',', array_map('intval', $cateIds));
            $this->execute("DELETE FROM `oa_flow` WHERE `cate_id` IN ({$in})");
        }

        // 3. 删除消息模板与审批类型
        $this->execute("DELETE FROM `oa_template` WHERE `name` = 'vcc_payment'");
        $this->execute("DELETE FROM `oa_flow_cate` WHERE `name` = 'vcc_payment'");
    }

    /**
     * 从所有角色的 rules 字段中剔除指定权限节点 ID
     *
     * @param array<int, int|string> $ruleIds
     */
    protected function removeRulesFromGroups(array $ruleIds): void
    {
        $db      = $this->getAdapter()->getConnection();
        $ruleIds = array_map('strval', $ruleIds);
        $groups  = $db->query("SELECT id, rules FROM `oa_admin_group`")->fetchAll(\PDO::FETCH_ASSOC);
        foreach ($groups as $group) {
            $rules = array_filter(explode(',', (string) $group['rules']), static fn($v) => $v !== '');
            $kept  = array_values(array_diff($rules, $ruleIds));
            if (count($kept) !== count($rules)) {
                $newRules = implode(',', $kept);
                $this->execute("UPDATE `oa_admin_group` SET `rules` = '{$newRules}' WHERE `id` = {$group['id']}");
            }
        }
    }
}
