import { Inject, Injectable } from '@nestjs/common';
import { Page, Prisma } from '@prisma/client';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { PrismaService } from 'nestjs-prisma';
import { Logger } from 'winston';

import { ConfigService } from '@nestjs/config';
import { createSafeLogData } from '../../lib/safe-log.util';

@Injectable()
export class PageService {
  constructor(
    private prisma: PrismaService,
    private readonly config: ConfigService,
    @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
  ) {}

  async createOne(pageCreateArgs: Prisma.PageCreateArgs) {
    this.logger.info(
      '[Page] Creating page',
      createSafeLogData({
        operation: 'CREATE',
        table: 'page',
        data: pageCreateArgs.data,
      }),
    );
    const result = await this.prisma.page.create(pageCreateArgs);
    this.logger.info(
      '[Page] Page created successfully',
      createSafeLogData({
        operation: 'CREATE',
        table: 'page',
        result: result,
      }),
    );
    return result;
  }

  /**
   * 在事务中创建 page 及其 pageResource 关系
   * @param pageData 页面创建数据
   * @param resourceIds 资源 ID 数组（可选）
   */
  async createPageWithResources(
    pageData: Prisma.PageCreateInput,
    resourceIds?: { resourceId: number; actions: string[] }[],
  ) {
    // 如果没有 resourceIds，直接创建页面即可
    if (!resourceIds || resourceIds.length === 0) {
      this.logger.info(
        '[Page] Creating page without resources',
        createSafeLogData({
          operation: 'CREATE',
          table: 'page',
          data: pageData,
        }),
      );
      const result = await this.prisma.page.create({
        data: pageData,
      });
      this.logger.info(
        '[Page] Page created successfully',
        createSafeLogData({
          operation: 'CREATE',
          table: 'page',
          result: result,
        }),
      );
      return result;
    }
    //有 resourceIds 时，使用交互式事务确保原子性
    this.logger.info(
      '[Page] Creating page with resources in transaction',
      createSafeLogData({
        operation: 'CREATE_WITH_RESOURCES',
        table: 'page',
        pageData: pageData,
        resourceIds: resourceIds,
      }),
    );
    return await this.prisma.$transaction(async (tx) => {
      // 1. 创建页面
      const page = await tx.page.create({
        data: pageData,
      });
      this.logger.info(
        '[Page] Page created in transaction',
        createSafeLogData({
          operation: 'CREATE',
          table: 'page',
          result: page,
        }),
      );

      // 2. 创建 pageResource 关系
      const pageResourcesData = resourceIds.map((item) => ({
        pageId: page.id,
        resourceId: item.resourceId,
        actions: item.actions as Prisma.InputJsonValue,
      }));

      this.logger.info(
        '[PageResource] Creating page resources in transaction',
        createSafeLogData({
          operation: 'CREATE_MANY',
          table: 'pageResource',
          data: pageResourcesData,
        }),
      );
      const createResult = await tx.pageResource.createMany({
        data: pageResourcesData,
        skipDuplicates: true,
      });
      this.logger.info(
        '[PageResource] Page resources created in transaction',
        createSafeLogData({
          operation: 'CREATE_MANY',
          table: 'pageResource',
          count: createResult.count,
        }),
      );

      return page;
    });
  }

  async createMany(data: Prisma.PageCreateManyArgs['data']) {
    this.logger.info(
      '[Page] Creating multiple pages',
      createSafeLogData({
        operation: 'CREATE_MANY',
        table: 'page',
        count: Array.isArray(data) ? data.length : 1,
        data: data,
      }),
    );
    const result = await this.prisma.page.createMany({
      data,
      skipDuplicates: true,
    });
    this.logger.info(
      '[Page] Multiple pages created successfully',
      createSafeLogData({
        operation: 'CREATE_MANY',
        table: 'page',
        count: result.count,
      }),
    );
    return result;
  }

  async findMany(
    pageFindManyArgs: Prisma.PageFindManyArgs,
  ): Promise<{ itemCount: number; entities: Page[] }> {
    const itemCount = await this.prisma.page.count({
      where: pageFindManyArgs.where,
    });
    const entities = await this.prisma.page.findMany(pageFindManyArgs);
    return { itemCount, entities };
  }

  async findUnique(id: number, select: Prisma.PageFindUniqueArgs['select']) {
    return await this.prisma.page.findUnique({
      where: { id: id },
      select,
    });
  }

  async updateMany(pageUpdateManyArgs: Prisma.PageUpdateManyArgs) {
    this.logger.info(
      '[Page] Updating multiple pages',
      createSafeLogData({
        operation: 'UPDATE_MANY',
        table: 'page',
        where: pageUpdateManyArgs.where,
        data: pageUpdateManyArgs.data,
      }),
    );
    const result = await this.prisma.page.updateMany(pageUpdateManyArgs);
    this.logger.info(
      '[Page] Multiple pages updated successfully',
      createSafeLogData({
        operation: 'UPDATE_MANY',
        table: 'page',
        count: result.count,
      }),
    );
    return result;
  }

  async updateUnique(id: number, data: Prisma.PageUpdateManyArgs['data']) {
    const oldData = await this.prisma.page.findUnique({ where: { id } });
    this.logger.info(
      '[Page] Updating page',
      createSafeLogData({
        operation: 'UPDATE',
        table: 'page',
        id: id,
        oldData: oldData,
        newData: data,
      }),
    );
    const result = await this.prisma.page.update({
      where: { id: id },
      data,
    });
    this.logger.info(
      '[Page] Page updated successfully',
      createSafeLogData({
        operation: 'UPDATE',
        table: 'page',
        id: id,
        result: result,
      }),
    );
    return result;
  }

  /**
   * 在事务中更新 page 及其 pageResource 关系，并同步更新 roleResource
   *
   * ========== 整体逻辑说明 ==========
   * 数据关系：role -> rolePages -> page -> pageResource -> resource
   *          role -> roleResource -> resource
   *
   * 核心原则：
   * 1. roleResource 是角色所有页面资源的【并集】
   * 2. pageResource 的变化会影响 roleResource，但不会逆向影响其他页面
   * 3. 只更新变化的部分，避免全量删除重建
   *
   * 处理策略：
   * - 新增资源：将当前页面的 actions 与 roleResource 已有的 actions 取并集
   *   （因为新增时 roleResource 可能因其他页面已经存在，直接合并即可）
   * - 删除资源：检查角色的其他页面是否还有该资源，没有则删除 roleResource，有则跳过
   * - 修改资源：将当前页面的【新 actions】与【其他页面】的 actions 取并集
   *   （注意：不能与 roleResource 已有 actions 合并，因为那会保留当前页面的旧 actions）
   * ================================
   *
   * @param id 页面 ID
   * @param pageData 页面更新数据
   * @param resourceIds 资源 ID 数组（可选）
   */
  async updatePageWithResources(
    id: number,
    pageData: Prisma.PageUpdateManyArgs['data'],
    resourceIds?: { resourceId: number; actions: string[] }[],
  ) {
    // 使用交互式事务确保所有操作的原子性和一致性
    return await this.prisma.$transaction(async (tx) => {
      // Step 1: 更新页面基本信息
      const oldPage = await tx.page.findUnique({ where: { id } });
      this.logger.info(
        '[Page] Updating page in transaction',
        createSafeLogData({
          operation: 'UPDATE',
          table: 'page',
          id: id,
          oldData: oldPage,
          newData: pageData,
        }),
      );
      const page = await tx.page.update({
        where: { id },
        data: pageData,
      });
      this.logger.info(
        '[Page] Page updated in transaction',
        createSafeLogData({
          operation: 'UPDATE',
          table: 'page',
          id: id,
          result: page,
        }),
      );

      // Step 2: 处理 pageResource 关系更新
      if (resourceIds !== undefined && resourceIds !== null) {
        // 2.1 在事务内获取当前页面的旧资源配置（确保数据一致性）
        const oldPageResources = await tx.pageResource.findMany({
          where: { pageId: id },
          select: { resourceId: true, actions: true },
        });

        // 构建旧资源映射: resourceId -> actions[]
        const oldResourceMap = new Map<number, string[]>();
        for (const pr of oldPageResources) {
          oldResourceMap.set(pr.resourceId, this.parseActions(pr.actions));
        }

        // 构建新资源映射: resourceId -> actions[]
        const newResourceMap = new Map<number, string[]>();
        for (const item of resourceIds) {
          newResourceMap.set(item.resourceId, item.actions);
        }

        // 2.2 计算变化：新增的资源、删除的资源、修改的资源
        const addedResources: { resourceId: number; actions: string[] }[] = [];
        const removedResourceIds: number[] = [];
        const modifiedResources: {
          resourceId: number;
          newActions: string[];
        }[] = [];

        // 找出新增和修改的资源
        for (const [resourceId, newActions] of newResourceMap) {
          const oldActions = oldResourceMap.get(resourceId);
          if (!oldActions) {
            // 新增的资源
            addedResources.push({ resourceId, actions: newActions });
          } else {
            // 检查是否有修改（actions 变化）
            const oldSet = new Set(oldActions);
            const newSet = new Set(newActions);
            const isChanged =
              oldSet.size !== newSet.size ||
              [...oldSet].some((a) => !newSet.has(a));
            if (isChanged) {
              modifiedResources.push({ resourceId, newActions });
            }
          }
        }

        // 找出删除的资源
        for (const [resourceId] of oldResourceMap) {
          if (!newResourceMap.has(resourceId)) {
            removedResourceIds.push(resourceId);
          }
        }

        // 2.3 更新 pageResource 表（先删后建）
        this.logger.info(
          '[PageResource] Deleting old page resources',
          createSafeLogData({
            operation: 'DELETE_MANY',
            table: 'pageResource',
            pageId: id,
            oldResources: oldPageResources,
          }),
        );
        const deleteResult = await tx.pageResource.deleteMany({
          where: { pageId: id },
        });
        this.logger.info(
          '[PageResource] Old page resources deleted',
          createSafeLogData({
            operation: 'DELETE_MANY',
            table: 'pageResource',
            pageId: id,
            count: deleteResult.count,
          }),
        );

        if (resourceIds.length > 0) {
          const pageResourcesData = resourceIds.map((item) => ({
            pageId: id,
            resourceId: item.resourceId,
            actions: item.actions as Prisma.InputJsonValue,
          }));

          this.logger.info(
            '[PageResource] Creating new page resources',
            createSafeLogData({
              operation: 'CREATE_MANY',
              table: 'pageResource',
              pageId: id,
              data: pageResourcesData,
            }),
          );
          const createResult = await tx.pageResource.createMany({
            data: pageResourcesData,
            skipDuplicates: true,
          });
          this.logger.info(
            '[PageResource] New page resources created',
            createSafeLogData({
              operation: 'CREATE_MANY',
              table: 'pageResource',
              pageId: id,
              count: createResult.count,
            }),
          );
        }

        // Step 3: 只有当资源有变化时，才需要更新 roleResource
        const hasResourceChanges =
          addedResources.length > 0 ||
          removedResourceIds.length > 0 ||
          modifiedResources.length > 0;

        if (hasResourceChanges) {
          // 3.1 在事务内查询所有关联此 page 的 role（通过 rolePages）
          const affectedRoles = await tx.rolePages.findMany({
            where: { pageId: id },
            select: { roleId: true },
          });

          const affectedRoleIds = affectedRoles.map((r) => r.roleId);

          if (affectedRoleIds.length === 0) {
            // 没有受影响的角色，直接返回更新后的页面
            return page;
          }

          // 3.2 获取受影响的 resourceIds
          const affectedResourceIds = [
            ...addedResources.map((r) => r.resourceId),
            ...removedResourceIds,
            ...modifiedResources.map((r) => r.resourceId),
          ];

          // 3.3 在事务内一次性查询所有受影响角色的 roleResource（只查受影响的资源）
          const existingRoleResources = await tx.roleResource.findMany({
            where: {
              roleId: { in: affectedRoleIds },
              resourceId: { in: affectedResourceIds },
            },
            select: { roleId: true, resourceId: true, actions: true },
          });

          // 构建 roleResource 映射: `${roleId}-${resourceId}` -> actions[]
          const roleResourceMap = new Map<string, string[]>();
          for (const rr of existingRoleResources) {
            const key = `${rr.roleId}-${rr.resourceId}`;
            roleResourceMap.set(key, this.parseActions(rr.actions));
          }

          // 3.4 查询其他页面的资源信息（用于删除和修改资源时的判断）
          // otherPagesResourceSet: 用于判断删除时其他页面是否还有该资源
          // otherPagesActionsMap: 用于修改时获取其他页面对该资源的 actions 并集
          const otherPagesResourceSet = new Set<string>(); // `${roleId}-${resourceId}`
          const otherPagesActionsMap = new Map<string, string[]>(); // `${roleId}-${resourceId}` -> actions 并集

          // 需要查询其他页面的资源：被删除的 + 被修改的
          const needCheckResourceIds = [
            ...removedResourceIds,
            ...modifiedResources.map((r) => r.resourceId),
          ];

          if (needCheckResourceIds.length > 0) {
            // 在事务内查询每个角色的其他页面
            const roleOtherPages = await tx.rolePages.findMany({
              where: {
                roleId: { in: affectedRoleIds },
                pageId: { not: id },
              },
              select: { roleId: true, pageId: true },
            });

            // 按角色分组其他页面 ID
            const roleToOtherPageIds = new Map<number, number[]>();
            for (const rp of roleOtherPages) {
              const pageIds = roleToOtherPageIds.get(rp.roleId) || [];
              pageIds.push(rp.pageId);
              roleToOtherPageIds.set(rp.roleId, pageIds);
            }

            // 在事务内查询其他页面中相关资源的详细信息（包括 actions）
            const allOtherPageIds = roleOtherPages.map((rp) => rp.pageId);
            if (allOtherPageIds.length > 0) {
              const otherPagesResources = await tx.pageResource.findMany({
                where: {
                  pageId: { in: allOtherPageIds },
                  resourceId: { in: needCheckResourceIds },
                },
                select: { pageId: true, resourceId: true, actions: true },
              });

              // 构建 pageId -> { resourceId -> actions } 映射
              const pageResourceActionsMap = new Map<
                number,
                Map<number, string[]>
              >();
              for (const pr of otherPagesResources) {
                let resourceMap = pageResourceActionsMap.get(pr.pageId);
                if (!resourceMap) {
                  resourceMap = new Map<number, string[]>();
                  pageResourceActionsMap.set(pr.pageId, resourceMap);
                }
                resourceMap.set(pr.resourceId, this.parseActions(pr.actions));
              }

              // 对每个角色，构建其其他页面的资源信息
              for (const [roleId, pageIds] of roleToOtherPageIds) {
                for (const pageId of pageIds) {
                  const resourceMap = pageResourceActionsMap.get(pageId);
                  if (resourceMap) {
                    for (const [resourceId, actions] of resourceMap) {
                      const key = `${roleId}-${resourceId}`;

                      // 标记该角色的其他页面有这个资源（用于删除判断）
                      otherPagesResourceSet.add(key);

                      // 合并其他页面对该资源的 actions（用于修改时取并集）
                      const existingActions =
                        otherPagesActionsMap.get(key) || [];
                      const mergedActions = new Set([
                        ...existingActions,
                        ...actions,
                      ]);
                      otherPagesActionsMap.set(key, Array.from(mergedActions));
                    }
                  }
                }
              }
            }
          }

          // Step 4: 对每个受影响的角色，在事务内更新 roleResource
          for (const roleId of affectedRoleIds) {
            // 4.1 处理删除的资源
            for (const resourceId of removedResourceIds) {
              const key = `${roleId}-${resourceId}`;
              if (otherPagesResourceSet.has(key)) {
                // 其他页面还有这个资源，跳过（roleResource 保持不变）
                continue;
              } else {
                // 其他页面没有这个资源，删除 roleResource
                const oldRoleResource = await tx.roleResource.findFirst({
                  where: { roleId, resourceId },
                });
                this.logger.info(
                  '[RoleResource] Deleting role resource (no other pages have this resource)',
                  createSafeLogData({
                    operation: 'DELETE_MANY',
                    table: 'roleResource',
                    roleId: roleId,
                    resourceId: resourceId,
                    oldData: oldRoleResource,
                  }),
                );
                const deleteResult = await tx.roleResource.deleteMany({
                  where: { roleId, resourceId },
                });
                this.logger.info(
                  '[RoleResource] Role resource deleted',
                  createSafeLogData({
                    operation: 'DELETE_MANY',
                    table: 'roleResource',
                    roleId: roleId,
                    resourceId: resourceId,
                    count: deleteResult.count,
                  }),
                );
              }
            }

            // 4.2 处理新增的资源
            for (const { resourceId, actions } of addedResources) {
              const key = `${roleId}-${resourceId}`;
              const existingActions = roleResourceMap.get(key) || [];

              // 合并当前页面的 actions 与已有的 roleResource actions（取并集）
              const mergedActions = new Set<string>([
                ...actions,
                ...existingActions,
              ]);

              this.logger.info(
                '[RoleResource] Upserting role resource (added resource)',
                createSafeLogData({
                  operation: 'UPSERT',
                  table: 'roleResource',
                  roleId: roleId,
                  resourceId: resourceId,
                  existingActions: existingActions,
                  newActions: actions,
                  mergedActions: Array.from(mergedActions),
                }),
              );
              const upsertResult = await tx.roleResource.upsert({
                where: { roleId_resourceId: { roleId, resourceId } },
                update: {
                  actions: Array.from(mergedActions) as Prisma.InputJsonValue,
                },
                create: {
                  roleId,
                  resourceId,
                  actions: Array.from(mergedActions) as Prisma.InputJsonValue,
                },
              });
              this.logger.info(
                '[RoleResource] Role resource upserted',
                createSafeLogData({
                  operation: 'UPSERT',
                  table: 'roleResource',
                  result: upsertResult,
                }),
              );
            }

            // 4.3 处理修改的资源
            // 注意：修改资源时，需要用当前页面的新 actions 与【其他页面】的 actions 取并集
            // 而不是与 roleResource 已有的 actions 取并集（因为那会包含当前页面的旧 actions）
            for (const { resourceId, newActions } of modifiedResources) {
              const key = `${roleId}-${resourceId}`;
              // 获取其他页面对该资源的 actions 并集
              const otherPagesActions = otherPagesActionsMap.get(key) || [];

              // 合并当前页面的新 actions 与其他页面的 actions（取并集）
              const mergedActions = new Set<string>([
                ...newActions,
                ...otherPagesActions,
              ]);

              this.logger.info(
                '[RoleResource] Upserting role resource (modified resource)',
                createSafeLogData({
                  operation: 'UPSERT',
                  table: 'roleResource',
                  roleId: roleId,
                  resourceId: resourceId,
                  newActions: newActions,
                  otherPagesActions: otherPagesActions,
                  mergedActions: Array.from(mergedActions),
                }),
              );
              const upsertResult = await tx.roleResource.upsert({
                where: { roleId_resourceId: { roleId, resourceId } },
                update: {
                  actions: Array.from(mergedActions) as Prisma.InputJsonValue,
                },
                create: {
                  roleId,
                  resourceId,
                  actions: Array.from(mergedActions) as Prisma.InputJsonValue,
                },
              });
              this.logger.info(
                '[RoleResource] Role resource upserted',
                createSafeLogData({
                  operation: 'UPSERT',
                  table: 'roleResource',
                  result: upsertResult,
                }),
              );
            }
          }
        }
      }
      // Step 5: 返回更新后的页面
      this.logger.info(
        '[Page] Page with resources updated successfully',
        createSafeLogData({
          operation: 'UPDATE_WITH_RESOURCES',
          table: 'page',
          id: id,
          finalResult: page,
        }),
      );
      return page;
    });
  }

  /**
   * 在事务中删除页面及其相关关系，并同步更新roleResource
   *
   * 删除逻辑说明：
   * 1. 删除pageResource中的页面和资源关系
   * 2. 检查哪些role拥有这个被删除的页面（通过rolePages）
   * 3. 检查页面拥有的资源是否在其他页面也存在
   * 4. 更新roleResource中的actions（降级处理）
   * 5. 删除rolePages关系
   * 6. 删除page本身
   *
   * @param id 要删除的页面ID
   */
  async deletePageWithResources(id: number) {
    return await this.prisma.$transaction(async (tx) => {
      // Step 1: 查询要删除的页面及其相关数据
      const pageToDelete = await tx.page.findUnique({
        where: { id },
        include: {
          pageResources: {
            include: {
              resource: true,
            },
          },
          rolePages: {
            include: {
              role: true,
            },
          },
        },
      });

      if (!pageToDelete) {
        throw new Error(`Page with id ${id} not found`);
      }

      this.logger.info(
        '[Page] Starting to delete page with resources',
        createSafeLogData({
          operation: 'DELETE_WITH_RESOURCES',
          table: 'page',
          id: id,
          pageData: pageToDelete,
        }),
      );

      // Step 2: 获取页面拥有的资源列表
      const pageResourceIds = pageToDelete.pageResources.map(
        (pr) => pr.resourceId,
      );
      const affectedRoleIds = pageToDelete.rolePages.map((rp) => rp.roleId);

      // Step 3: 查询其他页面中相关资源的信息
      let otherPagesResourceInfo = new Map<
        string,
        { hasResource: boolean; actions: string[] }
      >();

      if (pageResourceIds.length > 0 && affectedRoleIds.length > 0) {
        // 3.1 先查询资源信息，过滤掉通用资源
        const resourcesInfo = await tx.resource.findMany({
          where: { id: { in: pageResourceIds } },
          select: { id: true, isCommonResource: true },
        });

        // 过滤掉通用资源，只处理非通用资源
        const nonCommonResourceIds = resourcesInfo
          .filter((resource) => !resource.isCommonResource)
          .map((resource) => resource.id);

        // 如果没有非通用资源，跳过后续查询
        if (nonCommonResourceIds.length === 0) {
          // 只有通用资源，不需要查询其他页面信息
          otherPagesResourceInfo = new Map();
        } else {
          // 查询每个角色的其他页面
          const roleOtherPages = await tx.rolePages.findMany({
            where: {
              roleId: { in: affectedRoleIds },
              pageId: { not: id },
            },
            select: { roleId: true, pageId: true },
          });

          // 按角色分组其他页面ID
          const roleToOtherPageIds = new Map<number, number[]>();
          for (const rp of roleOtherPages) {
            const pageIds = roleToOtherPageIds.get(rp.roleId) || [];
            pageIds.push(rp.pageId);
            roleToOtherPageIds.set(rp.roleId, pageIds);
          }

          // 查询其他页面中相关资源的详细信息
          const allOtherPageIds = roleOtherPages.map((rp) => rp.pageId);
          if (allOtherPageIds.length > 0) {
            const otherPagesResources = await tx.pageResource.findMany({
              where: {
                pageId: { in: allOtherPageIds },
                resourceId: { in: pageResourceIds },
              },
              select: { pageId: true, resourceId: true, actions: true },
            });

            // 构建页面资源映射
            const pageResourceActionsMap = new Map<
              number,
              Map<number, string[]>
            >();
            for (const pr of otherPagesResources) {
              let resourceMap = pageResourceActionsMap.get(pr.pageId);
              if (!resourceMap) {
                resourceMap = new Map<number, string[]>();
                pageResourceActionsMap.set(pr.pageId, resourceMap);
              }
              resourceMap.set(pr.resourceId, this.parseActions(pr.actions));
            }

            // 对每个角色，构建其其他页面的资源信息
            for (const [roleId, pageIds] of roleToOtherPageIds) {
              for (const pageId of pageIds) {
                const resourceMap = pageResourceActionsMap.get(pageId);
                if (resourceMap) {
                  for (const [resourceId, actions] of resourceMap) {
                    const key = `${roleId}-${resourceId}`;
                    const existingInfo = otherPagesResourceInfo.get(key);

                    if (existingInfo) {
                      // 合并actions（取并集）
                      const mergedActions = new Set([
                        ...existingInfo.actions,
                        ...actions,
                      ]);
                      otherPagesResourceInfo.set(key, {
                        hasResource: true,
                        actions: Array.from(mergedActions),
                      });
                    } else {
                      otherPagesResourceInfo.set(key, {
                        hasResource: true,
                        actions: actions,
                      });
                    }
                  }
                }
              }
            }
          }
        }
      }

      // Step 4: 删除pageResource关系
      if (pageToDelete.pageResources.length > 0) {
        this.logger.info(
          '[PageResource] Deleting page resources',
          createSafeLogData({
            operation: 'DELETE_MANY',
            table: 'pageResource',
            pageId: id,
            count: pageToDelete.pageResources.length,
          }),
        );
        await tx.pageResource.deleteMany({
          where: { pageId: id },
        });
        this.logger.info(
          '[PageResource] Page resources deleted',
          createSafeLogData({
            operation: 'DELETE_MANY',
            table: 'pageResource',
            pageId: id,
          }),
        );
      }

      // Step 5: 更新roleResource（降级处理）
      if (affectedRoleIds.length > 0 && pageResourceIds.length > 0) {
        // 5.1 先查询资源信息，过滤掉通用资源
        const resourcesInfo = await tx.resource.findMany({
          where: { id: { in: pageResourceIds } },
          select: { id: true, isCommonResource: true },
        });

        // 过滤掉通用资源，只处理非通用资源
        const nonCommonResourceIds = resourcesInfo
          .filter((resource) => !resource.isCommonResource)
          .map((resource) => resource.id);

        if (nonCommonResourceIds.length > 0) {
          // 查询现有的roleResource关系（只查询非通用资源）
          const existingRoleResources = await tx.roleResource.findMany({
            where: {
              roleId: { in: affectedRoleIds },
              resourceId: { in: nonCommonResourceIds },
            },
            select: { roleId: true, resourceId: true, actions: true },
          });

          for (const roleResource of existingRoleResources) {
            const key = `${roleResource.roleId}-${roleResource.resourceId}`;
            const otherPagesInfo = otherPagesResourceInfo.get(key);

            if (otherPagesInfo && otherPagesInfo.hasResource) {
              // 其他页面还有这个资源，更新actions为其他页面的actions并集
              this.logger.info(
                '[RoleResource] Updating role resource actions (other pages have this resource)',
                createSafeLogData({
                  operation: 'UPDATE',
                  table: 'roleResource',
                  roleId: roleResource.roleId,
                  resourceId: roleResource.resourceId,
                  oldActions: this.parseActions(roleResource.actions),
                  newActions: otherPagesInfo.actions,
                }),
              );
              await tx.roleResource.update({
                where: {
                  roleId_resourceId: {
                    roleId: roleResource.roleId,
                    resourceId: roleResource.resourceId,
                  },
                },
                data: {
                  actions: otherPagesInfo.actions as Prisma.InputJsonValue,
                },
              });
            } else {
              // 其他页面没有这个资源，删除roleResource关系
              this.logger.info(
                '[RoleResource] Deleting role resource (no other pages have this resource)',
                createSafeLogData({
                  operation: 'DELETE',
                  table: 'roleResource',
                  roleId: roleResource.roleId,
                  resourceId: roleResource.resourceId,
                  oldActions: this.parseActions(roleResource.actions),
                }),
              );
              await tx.roleResource.delete({
                where: {
                  roleId_resourceId: {
                    roleId: roleResource.roleId,
                    resourceId: roleResource.resourceId,
                  },
                },
              });
            }
          }
        }
        // 通用资源保持不变，不需要处理
      }

      // Step 6: 删除rolePages关系
      if (pageToDelete.rolePages.length > 0) {
        this.logger.info(
          '[RolePages] Deleting role pages',
          createSafeLogData({
            operation: 'DELETE_MANY',
            table: 'rolePages',
            pageId: id,
            count: pageToDelete.rolePages.length,
          }),
        );
        await tx.rolePages.deleteMany({
          where: { pageId: id },
        });
        this.logger.info(
          '[RolePages] Role pages deleted',
          createSafeLogData({
            operation: 'DELETE_MANY',
            table: 'rolePages',
            pageId: id,
          }),
        );
      }

      // Step 7: 删除页面本身
      this.logger.info(
        '[Page] Deleting page',
        createSafeLogData({
          operation: 'DELETE',
          table: 'page',
          id: id,
          oldData: pageToDelete,
        }),
      );
      await tx.page.delete({
        where: { id },
      });
      this.logger.info(
        '[Page] Page deleted successfully',
        createSafeLogData({
          operation: 'DELETE',
          table: 'page',
          id: id,
        }),
      );

      return { count: 1 };
    });
  }

  /**
   * 解析 actions 字段（支持多种格式）
   */
  private parseActions(actions: any): string[] {
    if (!actions) return [];

    // 如果已经是数组，直接返回
    if (Array.isArray(actions)) {
      return actions.map(String).filter(Boolean);
    }

    // 如果是字符串，尝试解析为 JSON
    if (typeof actions === 'string') {
      try {
        const parsed = JSON.parse(actions);
        if (Array.isArray(parsed)) {
          return parsed.map(String).filter(Boolean);
        }
        // 如果不是数组，按逗号分隔
        return actions
          .split(',')
          .map((s) => s.trim())
          .filter(Boolean);
      } catch {
        // JSON 解析失败，按逗号分隔
        return actions
          .split(',')
          .map((s) => s.trim())
          .filter(Boolean);
      }
    }

    return [];
  }

  async deleteMany(pageDeleteManyArgs: Prisma.PageDeleteManyArgs) {
    const oldData = await this.prisma.page.findMany({
      where: pageDeleteManyArgs.where,
    });
    this.logger.info(
      '[Page] Deleting multiple pages',
      createSafeLogData({
        operation: 'DELETE_MANY',
        table: 'page',
        where: pageDeleteManyArgs.where,
        oldData: oldData,
      }),
    );
    const result = await this.prisma.page.deleteMany(pageDeleteManyArgs);
    this.logger.info(
      '[Page] Multiple pages deleted successfully',
      createSafeLogData({
        operation: 'DELETE_MANY',
        table: 'page',
        count: result.count,
      }),
    );
    return result;
  }

  async deleteUnique(id: number) {
    const oldData = await this.prisma.page.findUnique({ where: { id } });
    this.logger.info(
      '[Page] Deleting page',
      createSafeLogData({
        operation: 'DELETE',
        table: 'page',
        id: id,
        oldData: oldData,
      }),
    );
    await this.prisma.page.delete({
      where: { id: id },
    });
    this.logger.info(
      '[Page] Page deleted successfully',
      createSafeLogData({
        operation: 'DELETE',
        table: 'page',
        id: id,
      }),
    );
    return { count: 1 };
  }

  async count(pageCountArgs?: Prisma.PageCountArgs) {
    return await this.prisma.page.count(pageCountArgs);
  }

  async groupBy(pageGroupByArgs: Prisma.PageGroupByArgs) {
    return await this.prisma.page.groupBy(pageGroupByArgs as any);
  }

  async aggregate(pageAggregateArgs: Prisma.PageAggregateArgs) {
    return await this.prisma.page.aggregate(pageAggregateArgs);
  }
}
