/**
 * 表单管理聚合服务
 * 
 * 协调表单引擎和审批引擎，提供统一的表单管理功能
 */

import { Injectable, Logger, HttpStatus } from '@nestjs/common';
import { BusinessException } from '@common/exceptions/business.exception';
import { PrismaService } from '@core/database/prisma/prisma.service';
import { FormDefinitionService } from '@engines/form/form-engine/services/form-definition.service';
import { FormVersionService } from '@engines/form/form-engine/services/form-version.service';
import { FormTemplateService } from '@engines/form/form-engine/services/form-template.service';
import { DefinitionService } from '@engines/approval/definition.service';
import {
  CreateFormDefinitionDto,
  UpdateFormDefinitionDto,
  FormDefinitionListItem,
} from '../dto/form-definition.dto';
import {
  SaveDesignDto,
  SaveFormDesignDto,
  SaveProcessDesignDto,
  DesignDataResponse,
  SaveDesignResponse,
} from '../dto/form-design.dto';
import { QueryFormDefinitionsDto, PaginatedResponse } from '../dto/query.dto';
import {
  FormNotFoundException,
  FormDefinitionDisabledException,
  FormDefinitionArchivedException,
} from '../exceptions';
import { RegionId } from '../decorators/region.decorator';
import { safeFindUnique } from '../utils/prisma-error-handler';

@Injectable()
export class FormManagementService {
  private readonly logger = new Logger(FormManagementService.name);

  // 用于区域校验的 include 配置 (v2.0 更新: 使用 organizationRegions 替代 departmentRegions)
  private readonly orgRegionInclude = {
    organization: {
      include: {
        organizationRegions: {
          include: { region: true },
        },
      },
    },
  };

  constructor(
    private readonly prisma: PrismaService,
    private readonly formDefinitionService: FormDefinitionService,
    private readonly formVersionService: FormVersionService,
    private readonly formTemplateService: FormTemplateService,
    private readonly approvalDefinitionService: DefinitionService,
  ) {}

  // ============================================
  // 1. 表单定义管理（聚合）
  // ============================================

  /**
   * 获取表单定义列表（按组织和权限过滤）
   */
  async findAll(
    query: QueryFormDefinitionsDto,
    regionId: RegionId,
    userId: string,
    userPermissions: string[],
  ): Promise<PaginatedResponse<FormDefinitionListItem>> {
    const { page = 1, limit = 20, status, category, keyword, organizationId } = query;

    const where: any = {};

    if (status) {
      where.status = status;
    }

    if (category) {
      where.category = category;
    }

    // 组织筛选
    if (organizationId !== undefined) {
      where.organizationId = organizationId;
    }

    if (keyword) {
      where.OR = [
        { name: { contains: keyword, mode: 'insensitive' } },
        { key: { contains: keyword, mode: 'insensitive' } },
      ];
    }

    // 权限过滤：普通用户只看自己创建的，超管看所有
    // 但如果是用于使用表单（forUse=true），则不应用创建者过滤
    if (!query.forUse && !userPermissions.includes('form:admin')) {
      where.createdBy = userId;
    }

    // 查询所有符合条件的表单定义
    const allItems = await this.prisma.formDefinition.findMany({
      where,
      orderBy: { createdAt: 'desc' },
      include: {
        organization: {
          include: {
            organizationRegions: {
              include: {
                region: true, // ✅ 需要关联 region 表才能获取 code
              },
            },
          },
        },
        _count: {
          select: { versions: true },
        },
      },
    });

    // 在应用层过滤区域访问权限
    const filteredItems = allItems.filter((item) => {
      // 平台级表单（organizationId = null）：所有区域可用
      if (!item.organizationId) {
        return true;
      }
      
      // ✅ 表单管理场景：如果不是用于使用表单（forUse=false），放宽区域限制
      // 允许创建者/管理员看到他们创建的表单，不管当前在哪个区域
      if (!query.forUse) {
        this.logger.debug(`[findAll] 表单管理场景：表单 "${item.name}" 不进行区域过滤`);
        return true;
      }
      
      // 用于使用表单（forUse=true）：严格检查组织是否在用户所在区域运营
      if (item.organization && item.organization.organizationRegions) {
        // ✅ v2.0 修复：使用 organizationRegions 替代 departmentRegions
        const orgRegionCodes = item.organization.organizationRegions
          .map((r: any) => r.region?.code)
          .filter(Boolean); // 过滤掉 null/undefined
        
        this.logger.debug(`[findAll] 表单使用场景：表单 "${item.name}" 的组织区域: ${orgRegionCodes.join(', ')}, 用户区域: ${regionId}, 匹配: ${orgRegionCodes.includes(regionId)}`);
        return orgRegionCodes.includes(regionId);
      }
      
      this.logger.warn(`[findAll] 表单 "${item.name}" 被过滤掉：organization 或 organizationRegions 为空`);
      return false;
    });

    this.logger.log(`[findAll] 数据库查询到 ${allItems.length} 条表单定义`);
    this.logger.log(`[findAll] 区域过滤后 ${filteredItems.length} 条 (查询区域: ${regionId})`);

    // 分页
    const total = filteredItems.length;
    const totalPages = Math.ceil(total / limit);
    const skip = (page - 1) * limit;
    const paginatedItems = filteredItems.slice(skip, skip + limit);

    // 注入 activeSnapshotId（schema 上无反向 relation，分页后单次额外查询）
    const activeSnapshotMap = await this.loadActiveSnapshotMap(
      paginatedItems.map((it) => it.id),
    );

    return {
      items: paginatedItems.map((item) =>
        this.mapToListItem(item, activeSnapshotMap.get(item.id)),
      ),
      total,
      page,
      limit,
      totalPages,
      hasNext: page < totalPages,
      hasPrev: page > 1,
    };
  }

  /**
   * 创建表单定义（聚合操作）
   * 同时创建表单定义、表单版本、流程定义和流程版本
   */
  async create(
    dto: CreateFormDefinitionDto,
    regionId: RegionId,
    userId: string,
  ) {
    this.logger.log(
      `Creating form definition: ${dto.key} in region ${regionId}`,
    );

    // 检查 key 是否已存在
    const existingForm = await this.prisma.formDefinition.findUnique({
      where: { key: dto.key },
    });
    if (existingForm) {
      throw new BusinessException(
        `表单定义 key '${dto.key}' 已存在`,
        'FORM_KEY_ALREADY_EXISTS',
        HttpStatus.CONFLICT,
        { key: dto.key },
      );
    }

    return this.prisma.$transaction(async (tx) => {
      // 1. 如果有模板 ID，先获取模板数据
      let templateData: any = null;
      if (dto.templateId) {
        templateData = await this.formTemplateService.findOne(dto.templateId);
      }

      // 2. 创建表单定义
      const formDefinition = await tx.formDefinition.create({
        data: {
          key: dto.key,
          slug: dto.key, // 初始 slug 与 key 相同
          name: dto.name,
          description: dto.description,
          category: dto.category || 'general',
          organizationId: dto.organizationId, // 使用提供的 organizationId
          defaultLocale: 'zh-CN',
          supportedLocales: ['zh-CN', 'en-US'],
          latestVersion: 1,
          status: 'DRAFT',
          requiresApproval: dto.requiresApproval ?? true,
          createdBy: userId,
        },
      });

      // 3. 创建初始表单版本
      const formVersion = await tx.formVersion.create({
        data: {
          definitionId: formDefinition.id,
          version: 1,
          schema: templateData?.template?.schema || {
            type: 'object',
            properties: {},
          },
          uiSchema: templateData?.template?.uiSchema || {},
          nameI18n: { 'zh-CN': dto.name, 'en-US': dto.name },
          status: 'DRAFT',
          isDefault: true,
          createdBy: userId,
        },
      });

      // 4. 创建流程定义
      const processKey = `${dto.key}_approval`;
      const processDefinition = await tx.approvalDefinition.create({
        data: {
          key: processKey,
          name: `${dto.name} 审批流程`,
          category: dto.category || 'general',
          description: `${dto.name} 的审批流程`,
          organizationId: dto.organizationId, // 使用与表单相同的 organizationId
          status: 'ACTIVE',
          createdBy: userId,
        },
      });

      // 5. 创建初始流程版本
      const defaultProcessModel = templateData?.template?.processModel || {
        nodes: [
          { id: 'start', type: 'START', name: '开始' },
          { id: 'end', type: 'END', name: '结束' },
        ],
        edges: [{ source: 'start', target: 'end' }],
      };

      const processVersion = await tx.approvalVersion.create({
        data: {
          definitionId: processDefinition.id,
          version: 1,
          name: 'v1.0',
          processModel: defaultProcessModel,
          settings: {},
          status: 'DRAFT',
          isDefault: true,
        },
      });

      // 6. 更新表单定义关联审批流程
      await tx.formDefinition.update({
        where: { id: formDefinition.id },
        data: { approvalProcessKey: processKey },
      });

      this.logger.log(`Form definition created: ${formDefinition.id}`);

      return {
        id: formDefinition.id,
        regionId,
        key: formDefinition.key,
        name: formDefinition.name,
        description: formDefinition.description,
        category: formDefinition.category,
        status: formDefinition.status,
        templateId: dto.templateId || null,
        formVersion: {
          id: formVersion.id,
          version: formVersion.version,
          versionName: null,
          status: formVersion.status,
        },
        processDefinition: {
          id: processDefinition.id,
          key: processDefinition.key,
          processVersion: {
            id: processVersion.id,
            version: processVersion.version,
            versionName: null,
            status: processVersion.status,
          },
        },
        createdAt: formDefinition.createdAt.toISOString(),
        createdBy: userId,
      };
    });
  }

  /**
   * 获取表单详情（含流程）
   */
  async findOne(id: string, regionId: RegionId) {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: {
          organization: {
            include: {
              organizationRegions: {
                include: {
                  region: true, // ✅ v2.0: 需要关联 region 表才能获取 code
                },
              },
            },
          },
          versions: {
            orderBy: { version: 'desc' },
            take: 1,
          },
        },
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证（查看表单详情）
    // this.validateRegionAccess(form, regionId);

    // 获取关联的流程定义
    let processDefinition = null;
    if (form.approvalProcessKey) {
      processDefinition = await this.prisma.approvalDefinition.findUnique({
        where: { key: form.approvalProcessKey },
        include: {
          versions: {
            orderBy: { version: 'desc' },
            take: 1,
          },
        },
      });
    }

    return {
      id: form.id,
      regionId,
      key: form.key,
      name: form.name,
      description: form.description,
      category: form.category,
      status: form.status,
      formVersion: form.versions[0]
        ? {
            id: form.versions[0].id,
            version: form.versions[0].version,
            versionName: form.versions[0].changelog,
            status: form.versions[0].status,
          }
        : null,
      processDefinition: processDefinition
        ? {
            id: processDefinition.id,
            key: processDefinition.key,
            processVersion: processDefinition.versions[0]
              ? {
                  id: processDefinition.versions[0].id,
                  version: processDefinition.versions[0].version,
                  versionName: processDefinition.versions[0].name,
                  status: processDefinition.versions[0].status,
                }
              : null,
          }
        : null,
      createdAt: form.createdAt.toISOString(),
      updatedAt: form.updatedAt.toISOString(),
    };
  }

  /**
   * 更新表单定义
   */
  async update(
    id: string,
    dto: UpdateFormDefinitionDto,
    regionId: RegionId,
    userId: string,
  ) {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: this.orgRegionInclude,
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证（更新表单定义）
    // this.validateRegionAccess(form, regionId);

    const updated = await this.prisma.formDefinition.update({
      where: { id },
      data: {
        ...dto,
        updatedBy: userId,
      },
    });

    return {
      id: updated.id,
      regionId,
      key: updated.key,
      name: updated.name,
      description: updated.description,
      category: updated.category,
      status: updated.status,
      icon: updated.icon,
      color: updated.color,
      updatedAt: updated.updatedAt.toISOString(),
    };
  }

  /**
   * 删除表单定义
   * 注意：管理操作不强制区域验证，允许管理员删除他们有权限管理的表单
   */
  async remove(id: string, regionId: RegionId) {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: {
          ...this.orgRegionInclude,
          _count: { select: { instances: true } },
        },
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证
    // 允许管理员删除他们有权限管理的表单，不管当前在哪个区域
    // this.validateRegionAccess(form, regionId);

    // 检查是否有实例
    if ((form as any)._count.instances > 0) {
      throw new FormDefinitionArchivedException(id);
    }

    await this.prisma.formDefinition.delete({ where: { id } });

    return {
      id,
      deleted: true,
    };
  }

  // ============================================
  // 2. 设计器（聚合）
  // ============================================

  /**
   * 获取设计数据
   * 注意：设计器场景不强制区域验证，允许设计者访问他们有权限设计的表单
   */
  async getDesignData(
    id: string,
    regionId: RegionId,
  ): Promise<DesignDataResponse> {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: {
          ...this.orgRegionInclude,
          versions: {
            where: { status: 'DRAFT' },
            orderBy: { version: 'desc' },
            take: 1,
          },
        },
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 设计器场景：不强制区域验证
    // 设计者应该能够设计他们有权限设计的表单，不管当前在哪个区域
    // this.validateRegionAccess(form, regionId);

    // 如果没有草稿版本，获取最新版本
    let formVersion = form.versions[0];
    if (!formVersion) {
      const latestVersion = await this.prisma.formVersion.findFirst({
        where: { definitionId: id },
        orderBy: { version: 'desc' },
      });
      formVersion = latestVersion!;
    }

    // 获取流程版本
    let processVersion = null;
    if (form.approvalProcessKey) {
      const processDef = await this.prisma.approvalDefinition.findUnique({
        where: { key: form.approvalProcessKey },
        include: {
          versions: {
            where: { status: 'DRAFT' },
            orderBy: { version: 'desc' },
            take: 1,
          },
        },
      });

      if (processDef) {
        processVersion = processDef.versions[0];
        if (!processVersion) {
          processVersion = await this.prisma.approvalVersion.findFirst({
            where: { definitionId: processDef.id },
            orderBy: { version: 'desc' },
          });
        }
      }
    }

    return {
      formDefinition: {
        id: form.id,
        key: form.key,
        name: form.name,
      },
      formVersion: {
        id: formVersion.id,
        version: formVersion.version,
        status: formVersion.status,
        schema: formVersion.schema,
        uiSchema: formVersion.uiSchema,
      },
      processVersion: processVersion
        ? {
            id: processVersion.id,
            version: processVersion.version,
            status: processVersion.status,
            model: processVersion.processModel as any,
          }
        : {
            id: '',
            version: 1,
            status: 'DRAFT',
            model: {
              nodes: [
                { id: 'start', type: 'START', name: '开始' },
                { id: 'end', type: 'END', name: '结束' },
              ],
              edges: [{ source: 'start', target: 'end' }],
            },
          },
    };
  }

  /**
   * 保存全部设计（表单 + 流程）
   */
  async saveDesign(
    id: string,
    dto: SaveDesignDto,
    regionId: RegionId,
    userId: string,
  ): Promise<SaveDesignResponse> {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: this.orgRegionInclude,
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证（保存设计）
    // this.validateRegionAccess(form, regionId);

    return this.prisma.$transaction(async (tx) => {
      // 1. 更新或创建表单版本
      const formVersion = await this.saveFormDesignInternal(
        tx,
        id,
        dto.formDesign,
        userId,
      );

      // 2. 更新或创建流程版本
      let processVersion = null;
      if (form.approvalProcessKey) {
        const processDef = await tx.approvalDefinition.findUnique({
          where: { key: form.approvalProcessKey },
        });
        if (processDef) {
          processVersion = await this.saveProcessDesignInternal(
            tx,
            processDef.id,
            dto.processDesign,
            userId,
          );
        }
      }

      return {
        formVersionId: formVersion.id,
        processVersionId: processVersion?.id || '',
        savedAt: new Date().toISOString(),
      };
    });
  }

  /**
   * 保存表单设计
   */
  async saveFormDesign(
    id: string,
    dto: SaveFormDesignDto,
    regionId: RegionId,
    userId: string,
  ) {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: this.orgRegionInclude,
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证（保存表单设计）
    // this.validateRegionAccess(form, regionId);

    const formVersion = await this.saveFormDesignInternal(
      this.prisma,
      id,
      dto,
      userId,
    );

    return {
      formVersionId: formVersion.id,
      savedAt: new Date().toISOString(),
    };
  }

  /**
   * 保存流程设计
   */
  async saveProcessDesign(
    id: string,
    dto: SaveProcessDesignDto,
    regionId: RegionId,
    userId: string,
  ) {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: this.orgRegionInclude,
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证（保存流程设计）
    // this.validateRegionAccess(form, regionId);

    if (!form.approvalProcessKey) {
      throw new FormNotFoundException(id, regionId);
    }

    const processDef = await this.prisma.approvalDefinition.findUnique({
      where: { key: form.approvalProcessKey },
    });

    if (!processDef) {
      throw new FormNotFoundException(id, regionId);
    }

    const processVersion = await this.saveProcessDesignInternal(
      this.prisma,
      processDef.id,
      dto,
      userId,
    );

    return {
      processVersionId: processVersion.id,
      savedAt: new Date().toISOString(),
    };
  }

  // ============================================
  // 私有辅助方法
  // ============================================

  private validateRegionAccess(form: any, regionId: RegionId) {
    // 平台级表单：所有区域可访问
    if (!form.organizationId) {
      return;
    }
    
    // 组织专属表单：检查组织是否在当前区域运营
    if (form.organization && form.organization.organizationRegions) {
      // ✅ v2.0: 使用 organizationRegions 替代 departmentRegions
      const orgRegionCodes = form.organization.organizationRegions
        .map((r: any) => r.region?.code)
        .filter(Boolean);
      
      if (!orgRegionCodes.includes(regionId)) {
        this.logger.warn(`[validateRegionAccess] 表单 ${form.id} 的组织区域 [${orgRegionCodes.join(', ')}] 不包含用户区域 ${regionId}`);
        throw new FormNotFoundException(form.id, regionId);
      }
      
      this.logger.debug(`[validateRegionAccess] 表单 ${form.id} 区域校验通过: ${regionId} in [${orgRegionCodes.join(', ')}]`);
    }
  }

  private mapToListItem(
    item: any,
    activeSnapshotId?: string,
  ): FormDefinitionListItem {
    return {
      id: item.id,
      organizationId: item.organizationId,
      key: item.key,
      name: item.name,
      description: item.description,
      category: item.category,
      status: item.status,
      requiresApproval: item.requiresApproval,
      approvalProcessKey: item.approvalProcessKey,
      activeSnapshotId,
      currentVersion: item.latestVersion,
      createdAt: item.createdAt.toISOString(),
      updatedAt: item.updatedAt.toISOString(),
      createdBy: item.createdBy,
    };
  }

  /// 批量加载 ACTIVE 快照 ID（formDefinitionId → snapshotId）
  /// schema 上 ReleaseSnapshot 没有反向 relation 到 FormDefinition，所以走单独查询。
  /// `@@unique([formDefinitionId, status])` 保证每个 formDef 至多一条 ACTIVE。
  private async loadActiveSnapshotMap(
    formDefinitionIds: string[],
  ): Promise<Map<string, string>> {
    if (formDefinitionIds.length === 0) {
      return new Map();
    }
    const snapshots = await this.prisma.releaseSnapshot.findMany({
      where: {
        formDefinitionId: { in: formDefinitionIds },
        status: 'ACTIVE',
      },
      select: { id: true, formDefinitionId: true },
    });
    return new Map(snapshots.map((s) => [s.formDefinitionId, s.id]));
  }

  private async saveFormDesignInternal(
    tx: any,
    definitionId: string,
    dto: SaveFormDesignDto,
    userId: string,
  ) {
    // 查找草稿版本
    let draftVersion = await tx.formVersion.findFirst({
      where: {
        definitionId,
        status: 'DRAFT',
      },
      orderBy: { version: 'desc' },
    });

    if (draftVersion) {
      // 更新现有草稿
      return tx.formVersion.update({
        where: { id: draftVersion.id },
        data: {
          schema: dto.schema,
          uiSchema: dto.uiSchema,
        },
      });
    } else {
      // 创建新版本
      const latestVersion = await tx.formVersion.findFirst({
        where: { definitionId },
        orderBy: { version: 'desc' },
      });

      const newVersion = (latestVersion?.version || 0) + 1;

      // 更新表单定义的最新版本号
      await tx.formDefinition.update({
        where: { id: definitionId },
        data: { latestVersion: newVersion },
      });

      return tx.formVersion.create({
        data: {
          definitionId,
          version: newVersion,
          schema: dto.schema,
          uiSchema: dto.uiSchema,
          nameI18n: latestVersion?.nameI18n || { 'zh-CN': '', 'en-US': '' },
          status: 'DRAFT',
          isDefault: false,
          createdBy: userId,
        },
      });
    }
  }

  private async saveProcessDesignInternal(
    tx: any,
    definitionId: string,
    dto: SaveProcessDesignDto,
    userId: string,
  ) {
    // 查找草稿版本
    let draftVersion = await tx.approvalVersion.findFirst({
      where: {
        definitionId,
        status: 'DRAFT',
      },
      orderBy: { version: 'desc' },
    });

    if (draftVersion) {
      // 更新现有草稿
      return tx.approvalVersion.update({
        where: { id: draftVersion.id },
        data: {
          processModel: {
            nodes: dto.nodes,
            edges: dto.edges,
          },
        },
      });
    } else {
      // 创建新版本
      const latestVersion = await tx.approvalVersion.findFirst({
        where: { definitionId },
        orderBy: { version: 'desc' },
      });

      const newVersion = (latestVersion?.version || 0) + 1;

      // 更新流程定义的最新版本号
      await tx.approvalDefinition.update({
        where: { id: definitionId },
        data: { latestVersion: newVersion },
      });

      return tx.approvalVersion.create({
        data: {
          definitionId,
          version: newVersion,
          name: `v${newVersion}.0`,
          processModel: {
            nodes: dto.nodes,
            edges: dto.edges,
          },
          settings: {},
          status: 'DRAFT',
          isDefault: false,
        },
      });
    }
  }

  // ============================================
  // 3. 表单定义状态管理
  // ============================================

  /**
   * 归档表单定义
   */
  async archive(id: string, regionId: RegionId, userId: string) {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: {
          ...this.orgRegionInclude,
          _count: {
            select: {
              instances: {
                where: {
                  status: { in: ['PENDING_APPROVAL'] },
                },
              },
            },
          },
        },
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证（归档表单）
    // this.validateRegionAccess(form, regionId);

    // 检查是否已归档
    if (form.status === 'ARCHIVED') {
      return {
        id,
        status: 'ARCHIVED',
        message: '表单已处于归档状态',
      };
    }

    // 检查是否有审批中的实例
    if ((form as any)._count.instances > 0) {
      throw new BusinessException(
        '表单有正在审批的实例，不能归档',
        'HAS_PENDING_INSTANCES',
        HttpStatus.CONFLICT,
        { formId: id, pendingCount: (form as any)._count.instances },
      );
    }

    const updated = await this.prisma.formDefinition.update({
      where: { id },
      data: {
        status: 'ARCHIVED',
        updatedBy: userId,
      },
    });

    this.logger.log(`Form ${id} archived by ${userId}`);

    return {
      id: updated.id,
      status: updated.status,
      archivedAt: updated.updatedAt.toISOString(),
      message: '表单已归档',
    };
  }

  /**
   * 禁用表单定义
   */
  async disable(id: string, regionId: RegionId, userId: string) {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: this.orgRegionInclude,
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证（禁用表单）
    // this.validateRegionAccess(form, regionId);

    // 只有 PUBLISHED 状态可以禁用
    if (form.status !== 'PUBLISHED') {
      throw new BusinessException(
        `只有已发布的表单可以禁用，当前状态：${form.status}`,
        'INVALID_STATUS_TRANSITION',
        HttpStatus.BAD_REQUEST,
        { formId: id, currentStatus: form.status },
      );
    }

    const updated = await this.prisma.formDefinition.update({
      where: { id },
      data: {
        status: 'DISABLED',
        updatedBy: userId,
      },
    });

    this.logger.log(`Form ${id} disabled by ${userId}`);

    return {
      id: updated.id,
      status: updated.status,
      disabledAt: updated.updatedAt.toISOString(),
      message: '表单已禁用',
    };
  }

  /**
   * 启用表单定义
   */
  async enable(id: string, regionId: RegionId, userId: string) {
    const form = await safeFindUnique(() =>
      this.prisma.formDefinition.findUnique({
        where: { id },
        include: this.orgRegionInclude,
      }),
    );

    if (!form) {
      throw new FormNotFoundException(id, regionId);
    }

    // ✅ 管理操作：不强制区域验证（启用表单）
    // this.validateRegionAccess(form, regionId);

    // 只有 DISABLED 状态可以启用
    if (form.status !== 'DISABLED') {
      throw new BusinessException(
        `只有已禁用的表单可以启用，当前状态：${form.status}`,
        'INVALID_STATUS_TRANSITION',
        HttpStatus.BAD_REQUEST,
        { formId: id, currentStatus: form.status },
      );
    }

    const updated = await this.prisma.formDefinition.update({
      where: { id },
      data: {
        status: 'PUBLISHED',
        updatedBy: userId,
      },
    });

    this.logger.log(`Form ${id} enabled by ${userId}`);

    return {
      id: updated.id,
      status: updated.status,
      enabledAt: updated.updatedAt.toISOString(),
      message: '表单已启用',
    };
  }

  /**
   * 映射前端审批模式到后端工作流引擎格式
   * 前端: 'AND' | 'OR' | 'SEQUENTIAL' | 'SINGLE'
   * 后端: 'COUNTERSIGN' | 'OR_SIGN' | 'SEQUENTIAL'
   */
  private mapApprovalMode(frontendMode: string | undefined): string {
    const mode = frontendMode || 'OR';
    switch (mode) {
      case 'AND':
        return 'COUNTERSIGN';  // 会签：所有人都要通过
      case 'OR':
        return 'OR_SIGN';      // 或签：任一人通过即可
      case 'SEQUENTIAL':
        return 'SEQUENTIAL';   // 依次审批
      case 'SINGLE':
        return 'OR_SIGN';      // 单人审批（相当于或签）
      default:
        return 'OR_SIGN';      // 默认或签
    }
  }

  /**
   * 预览审批流程（含实际审批人）
   * 用于在表单提交前预计算每个节点的实际审批人
   */
  async previewProcessWithApprovers(
    formId: string,
    dto: { formData: Record<string, any>; departmentId?: string; initiatorId?: string },
    userId: string,
  ) {
    // 1. 获取表单定义
    const formDefinition = await this.prisma.formDefinition.findUnique({
      where: { id: formId },
    });

    if (!formDefinition) {
      throw new FormNotFoundException(formId);
    }

    // 2. 查询已发布的快照
    const activeSnapshot = await this.prisma.releaseSnapshot.findFirst({
      where: {
        formDefinitionId: formId,
        status: 'ACTIVE',
      },
    });

    if (!activeSnapshot || !activeSnapshot.processVersionId) {
      throw new BusinessException(
        '表单未发布或未绑定审批流程',
        'PROCESS_NOT_PUBLISHED',
        HttpStatus.NOT_FOUND,
      );
    }

    // 3. 获取流程版本（从 approval 模块）
    const processVersion = await this.prisma.approvalVersion.findUnique({
      where: { id: activeSnapshot.processVersionId },
    });

    if (!processVersion || !processVersion.processModel) {
      throw new BusinessException(
        '流程配置不存在',
        'PROCESS_CONFIG_NOT_FOUND',
        HttpStatus.NOT_FOUND,
      );
    }

    // 4. 获取发起人信息
    // ⭐ 使用 dto.initiatorId（如果提供）或当前登录用户ID
    const initiatorUserId = dto.initiatorId || userId;
    this.logger.log(`[previewProcessWithApprovers] 使用发起人ID: ${initiatorUserId}, 当前用户ID: ${userId}`);
    
    const initiator = await this.prisma.user.findUnique({
      where: { id: initiatorUserId },
      select: {
        id: true,
        displayName: true,
        avatar: true,
        departmentMemberships: {
          where: { leftAt: null },
          include: { department: true },
        },
      },
    });

    if (!initiator) {
      throw new BusinessException(
        '用户不存在',
        'USER_NOT_FOUND',
        HttpStatus.NOT_FOUND,
      );
    }

    // 5. 准备变量上下文
    const variables: Record<string, any> = {
      formData: dto.formData,
      initiatorId: initiatorUserId,
      departmentId:
        dto.departmentId || initiator.departmentMemberships[0]?.departmentId,
    };

    // 6. 遍历流程节点，计算每个节点的审批人
    const model = processVersion.processModel as any;
    const nodesWithApprovers: any[] = [];

    for (const node of model.nodes) {
      if (node.type === 'USER_TASK') {
        // 解析审批人
        const approvers = await this.resolveApproversForNode(
          node,
          initiatorUserId,
          variables,
        );

        nodesWithApprovers.push({
          id: node.id,
          type: node.type,
          name: node.name,
          approvers,
          approvalMode: this.mapApprovalMode(node.approvalMode || node.config?.approvalMode),  // ⭐ 映射前端模式到后端格式
          config: {
            ...node.config,
            approverDetails: approvers, // 添加到 config.approverDetails
          },
        });
      } else {
        // START、END、GATEWAY 节点直接添加
        nodesWithApprovers.push({
          id: node.id,
          type: node.type,
          name: node.name,
          approvers: [],
          config: node.config || {},
        });
      }
    }

    return {
      model: {
        nodes: nodesWithApprovers,
        edges: model.edges,
      },
      initiator: {
        id: initiator.id,
        name: initiator.displayName,
        avatar: initiator.avatar || undefined,
      },
    };
  }

  /**
   * 解析节点的审批人
   */
  private async resolveApproversForNode(
    node: any,
    initiatorId: string,
    variables: Record<string, any>,
  ): Promise<Array<{ id: string; name: string; avatar?: string; type?: string }>> {
    const approvers: string[] = [];
    let assignees = node.assignees || [];

    // 兼容旧版配置：从 config.approverType 生成 assignees
    if (!assignees.length && node.config?.approverType) {
      assignees = this.generateAssigneesFromConfig(node.config);
    }

    // 解析每个 assignee 表达式
    for (const expression of assignees) {
      try {
        const resolvedIds = await this.resolveApproverExpression(
          expression,
          initiatorId,
          variables,
        );
        approvers.push(...resolvedIds);
      } catch (error) {
        this.logger.warn(
          `Failed to resolve approver expression "${expression}": ${error.message}`,
        );
        // 继续处理其他表达式
      }
    }

    // 去重
    const uniqueApprovers = [...new Set(approvers)];

    // 获取用户详细信息
    const users = await this.prisma.user.findMany({
      where: { id: { in: uniqueApprovers }, status: 'ACTIVE' },
      select: {
        id: true,
        displayName: true,
        avatar: true,
      },
    });

    return users.map((u) => ({
      id: u.id,
      name: u.displayName,
      avatar: u.avatar || undefined,
      type: 'user',
    }));
  }

  /**
   * 从旧版 config 生成 assignees 表达式
   */
  private generateAssigneesFromConfig(config: any): string[] {
    const { approverType, managerLevel = 1, approvers, approverConfig } =
      config;

    switch (approverType) {
      case 'INITIATOR_MANAGER':
        return managerLevel === 1
          ? ['initiator:manager']
          : [`initiator:manager[${managerLevel}]`];
      case 'DEPT_MANAGER':
        return ['initiator:deptManager'];
      case 'MANAGER_CHAIN':
        return ['initiator:managerChain'];
      case 'FIXED_USER':
        return approvers?.map((id: string) => `user:${id}`) || [];
      case 'ROLE':
        return (
          approverConfig?.roles?.map((role: string) => `role:${role}`) || []
        );
      case 'FORM_FIELD':
        return approverConfig?.formField
          ? [`formField:${approverConfig.formField}`]
          : [];
      default:
        return [];
    }
  }

  /**
   * 解析单个审批人表达式
   */
  private async resolveApproverExpression(
    expression: string,
    initiatorId: string,
    variables: Record<string, any>,
  ): Promise<string[]> {
    // user:xxx
    if (expression.startsWith('user:')) {
      return [expression.replace('user:', '')];
    }

    // role:xxx
    if (expression.startsWith('role:')) {
      const roleCode = expression.replace('role:', '');
      const users = await this.prisma.user.findMany({
        where: {
          roles: {
            some: { role: { code: roleCode } },
          },
          status: 'ACTIVE',
        },
        select: { id: true },
      });
      return users.map((u) => u.id);
    }

    // department:xxx
    if (expression.startsWith('department:')) {
      const deptId = expression.replace('department:', '');
      const userDepts = await this.prisma.userDepartment.findMany({
        where: {
          departmentId: deptId,
          leftAt: null,
          user: { status: 'ACTIVE' },
        },
        select: { userId: true },
      });
      return userDepts.map((ud) => ud.userId);
    }

    // initiator:manager
    if (expression === 'initiator:manager') {
      const manager = await this.findUserManager(initiatorId, 1);
      return manager ? [manager] : [];
    }

    // initiator:manager[N]
    if (expression.startsWith('initiator:manager[')) {
      const level = parseInt(expression.match(/\[(\d+)\]/)?.[1] || '1');
      const manager = await this.findUserManager(initiatorId, level);
      return manager ? [manager] : [];
    }

    // initiator:deptManager
    if (expression === 'initiator:deptManager') {
      const deptManager = await this.findDepartmentManager(
        initiatorId,
        variables.departmentId,
      );
      return deptManager ? [deptManager] : [];
    }

    // initiator:managerChain
    if (expression.startsWith('initiator:managerChain')) {
      return this.findManagerChain(initiatorId);
    }

    // formField:xxx
    if (expression.startsWith('formField:')) {
      const fieldName = expression.replace('formField:', '');
      const value = variables.formData?.[fieldName];
      if (value) {
        // 假设字段值是用户 ID
        return Array.isArray(value) ? value : [value];
      }
      return [];
    }

    return [];
  }

  /**
   * 查找用户的上级（通过 UserDepartment.managerId）
   */
  private async findUserManager(
    userId: string,
    level: number = 1,
  ): Promise<string | null> {
    let currentUserId = userId;

    for (let i = 0; i < level; i++) {
      // 查找用户的主部门或第一个部门的上级
      const userDept = await this.prisma.userDepartment.findFirst({
        where: {
          userId: currentUserId,
          leftAt: null,
        },
        orderBy: { isPrimary: 'desc' },
        select: { managerId: true },
      });

      if (!userDept || !userDept.managerId) {
        return null;
      }

      currentUserId = userDept.managerId;
    }

    return currentUserId;
  }

  /**
   * 查找部门负责人（使用 Department.headId）
   */
  private async findDepartmentManager(
    userId: string,
    departmentId?: string,
  ): Promise<string | null> {
    if (!departmentId) {
      // 查找用户的主部门
      const userDept = await this.prisma.userDepartment.findFirst({
        where: { userId, leftAt: null },
        orderBy: { isPrimary: 'desc' },
        include: { department: true },
      });
      departmentId = userDept?.departmentId;
    }

    if (!departmentId) {
      return null;
    }

    const dept = await this.prisma.department.findUnique({
      where: { id: departmentId },
      select: { headId: true },
    });

    return dept?.headId || null;
  }

  /**
   * 查找上级链（通过 UserDepartment.managerId）
   */
  private async findManagerChain(userId: string): Promise<string[]> {
    const chain: string[] = [];
    let currentUserId = userId;

    while (true) {
      // 查找用户的主部门或第一个部门的上级
      const userDept = await this.prisma.userDepartment.findFirst({
        where: {
          userId: currentUserId,
          leftAt: null,
        },
        orderBy: { isPrimary: 'desc' },
        select: { managerId: true },
      });

      if (!userDept || !userDept.managerId) {
        break;
      }

      chain.push(userDept.managerId);
      currentUserId = userDept.managerId;

      // 防止无限循环
      if (chain.length > 10) {
        break;
      }
    }

    return chain;
  }
}
