import { Injectable } from '@nestjs/common';
import {
  TermMethodSchema,
  db,
  Staff,
  Term,
  Prisma,
  TermDto,
  TreeDataNode,
  UserProfile,
  getUniqueItems,
  RolePerms,
  TaxonomySlug,
  ObjectType,
  TermAncestry,
} from '@nice/common';
import { z } from 'zod';
import { BaseTreeService } from '../base/base.tree.service';
import EventBus, { CrudOperation } from '@server/utils/event-bus';
import { formatToTermTreeData, mapToTermSimpleTree } from './utils';

@Injectable()
export class TermService extends BaseTreeService<Prisma.TermDelegate> {
  constructor() {
    super(db, ObjectType.TERM, 'termAncestry', true);
  }

  async create(args: Prisma.TermCreateArgs, params?: { staff?: UserProfile }) {
    args.data.createdBy = params?.staff?.id;
    const result = await super.create(args);
    EventBus.emit('dataChanged', {
      type: this.objectType,
      operation: CrudOperation.CREATED,
      data: result,
    });
    return result;
  }
  async update(args: Prisma.TermUpdateArgs) {
    const result = await super.update(args);
    EventBus.emit('dataChanged', {
      type: this.objectType,
      operation: CrudOperation.UPDATED,
      data: result,
    });
    return result;
  }

  /**
   * 删除现有单位并清理DeptAncestry关系。
   * @param data - 用于删除现有单位的数据。
   * @returns 删除的单位对象。
   */
  async softDeleteByIds(ids: string[]) {
    const descendantIds = await this.getDescendantIds(ids, true);
    const result = await super.softDeleteByIds(descendantIds);
    EventBus.emit('dataChanged', {
      type: this.objectType,
      operation: CrudOperation.DELETED,
      data: result,
    });
    return result;
  }

  // async query(data: z.infer<typeof TermMethodSchema.findManyWithCursor>) {
  //   const { limit = 10, initialIds, taxonomyId, taxonomySlug } = data;
  //   // Fetch additional objects excluding initialIds
  //   const ids =
  //     typeof initialIds === 'string' ? [initialIds] : initialIds || [];
  //   const initialTerms = await db.term.findMany({
  //     where: {
  //       id: {
  //         in: ids,
  //       },
  //     },
  //     include: {
  //       domain: true,
  //       children: true,
  //     },
  //   });
  //   const terms = await db.term.findMany({
  //     where: {
  //       taxonomyId,
  //       taxonomy: taxonomySlug && { slug: taxonomySlug },
  //       deletedAt: null,
  //     },
  //     take: limit !== -1 ? limit! : undefined,
  //     include: {
  //       domain: true,
  //       taxonomy: true,
  //     },
  //     orderBy: [{ order: 'asc' }, { createdAt: 'desc' }],
  //   });

  //   const results = getUniqueItems(
  //     [...initialTerms, ...terms].filter(Boolean),
  //     'id',
  //   );
  //   return results;
  // }
  // /**

  async upsertTags(staff: UserProfile, tags: string[]) {
    const tagTax = await db.taxonomy.findFirst({
      where: {
        slug: TaxonomySlug.TAG,
      },
    });
    // 批量查找所有存在的标签
    const existingTerms = await db.term.findMany({
      where: {
        name: {
          in: tags,
        },
        taxonomyId: tagTax.id,
      },
    });

    // 找出不存在的标签
    const existingTagNames = new Set(existingTerms.map((term) => term.name));
    const newTags = tags.filter((tag) => !existingTagNames.has(tag));
    // 批量创建不存在的标签
    const newTerms = await Promise.all(
      newTags.map((tag) =>
        this.create({
          data: {
            name: tag,
            taxonomyId: tagTax.id,
            domainId: staff.domainId,
          },
        }),
      ),
    );

    // 合并现有标签和新创建的标签
    return [...existingTerms, ...newTerms];
  }

  // /**
  //  * 查找多个术语并生成TermDto对象。
  //  *
  //  * @param staff 当前操作的工作人员
  //  * @param ids 术语ID
  //  * @returns 包含详细信息的术语对象
  //  */
  // async findByIds(ids: string[], staff?: UserProfile) {
  //   const terms = await db.term.findMany({
  //     where: {
  //       id: {
  //         in: ids,
  //       },
  //     },
  //     include: {
  //       domain: true,
  //       children: true,
  //     },
  //   });
  //   return await Promise.all(
  //     terms.map(async (term) => {
  //       return await this.transformDto(term, staff);
  //     }),
  //   );
  // }
  // /**
  //  * 获取指定条件下的术语子节点。
  //  *
  //  * @param staff 当前操作的工作人员
  //  * @param data 查询条件
  //  * @returns 子节点术语列表
  //  */
  // async getChildren(
  //   staff: UserProfile,
  //   data: z.infer<typeof TermMethodSchema.getChildren>,
  // ) {
  //   const { parentId, domainId, taxonomyId, cursor, limit = 10 } = data;
  //   let queryCondition: Prisma.TermWhereInput = {
  //     taxonomyId,
  //     parentId: parentId,
  //     OR: [{ domainId: null }],
  //     deletedAt: null,
  //   };
  //   if (
  //     staff?.permissions?.includes(RolePerms.MANAGE_ANY_TERM) ||
  //     staff?.permissions?.includes(RolePerms.READ_ANY_TERM)
  //   ) {
  //     queryCondition.OR = undefined;
  //   } else {
  //     queryCondition.OR = queryCondition.OR.concat([
  //       { domainId: staff?.domainId },
  //       { domainId: null },
  //     ]);
  //   }
  //   const terms = await db.term.findMany({
  //     where: queryCondition,
  //     include: {
  //       children: {
  //         where: {
  //           deletedAt: null,
  //         },
  //       },
  //     },
  //     take: limit + 1,
  //     cursor: cursor
  //       ? { createdAt: cursor.split('_')[0], id: cursor.split('_')[1] }
  //       : undefined,
  //   });
  //   let nextCursor: typeof cursor | undefined = undefined;
  //   if (terms.length > limit) {
  //     const nextItem = terms.pop();
  //     nextCursor = `${nextItem.createdAt.toISOString()}_${nextItem!.id}`;
  //   }
  //   const termDtos = await Promise.all(
  //     terms.map((item) => this.transformDto(item, staff)),
  //   );
  //   return {
  //     items: termDtos,
  //     nextCursor,
  //   };
  // }

  async getTreeData(data: z.infer<typeof TermMethodSchema.getTreeData>) {
    const { taxonomyId, taxonomySlug, domainId } = data;
    let terms = [];
    if (taxonomyId) {
      terms = await db.term.findMany({
        where: { taxonomyId, domainId, deletedAt: null },
        include: { children: true },
        orderBy: [{ order: 'asc' }],
      });
    } else if (taxonomySlug) {
      terms = await db.term.findMany({
        where: {
          taxonomy: {
            slug: taxonomySlug,
          },
          deletedAt: null,
          domainId,
        },
        include: { children: true },
        orderBy: [{ order: 'asc' }],
      });
    }
    // Map to store terms by id for quick lookup
    const termMap = new Map<string, any>();
    terms.forEach((term) =>
      termMap.set(term.id, {
        ...term,
        children: [],
        key: term.id,
        value: term.id,
        title: term.name,
        isLeaf: true, // Initialize as true, will update later if it has children
      }),
    );
    // Root nodes collection
    const roots = [];
    // Build the tree structure iteratively
    terms.forEach((term) => {
      if (term.parentId) {
        const parent = termMap.get(term.parentId);
        if (parent) {
          parent.children.push(termMap.get(term.id));
          parent.isLeaf = false; // Update parent's isLeaf field
        }
      } else {
        roots.push(termMap.get(term.id));
      }
    });
    return roots as TreeDataNode[];
  }

  async getChildSimpleTree(
    staff: UserProfile | null | undefined, // 允许 staff 为 null 或 undefined
    data: z.infer<typeof TermMethodSchema.getSimpleTree>,
  ) {
    // 处理 staff 不存在的情况，设置默认值
    const domainId = staff?.domainId ?? null;
    const permissions = staff?.permissions ?? [];

    // 权限判断逻辑调整
    const hasAnyPerms = permissions.includes(RolePerms.MANAGE_ANY_TERM) ||
      permissions.includes(RolePerms.READ_ANY_TERM);

    const { termIds, parentId, taxonomyId } = data;
    const validTermIds = termIds?.filter((id) => id !== null) ?? [];
    const hasNullTermId = termIds?.includes(null) ?? false;

    const [childrenData, selfData] = await Promise.all([
      db.termAncestry.findMany({
        where: {
          ...(termIds && {
            OR: [
              ...(validTermIds.length ? [{ ancestorId: { in: validTermIds } }] : []),
              ...(hasNullTermId ? [{ ancestorId: null }] : []),
            ],
          }),
          descendant: {
            taxonomyId: taxonomyId,
            // 当 staff 不存在时 hasAnyPerms 自动为 false，会应用域过滤
            ...(hasAnyPerms ? {} : {
              OR: [
                { domainId: null },
                ...(domainId ? [{ domainId }] : []) // 如果 domainId 为 null 则不添加
              ].filter(Boolean) // 过滤空数组
            }),
          },
          ancestorId: parentId,
          relDepth: 1,
        },
        include: {
          descendant: { include: { children: true } },
        },
        orderBy: { descendant: { order: 'asc' } },
      }),
      termIds
        ? db.term.findMany({
          where: {
            ...(termIds && {
              OR: [
                ...(validTermIds.length ? [{ id: { in: validTermIds } }] : []),
              ],
            }),
            taxonomyId: taxonomyId,
            // 同理处理第二个查询的权限
            ...(hasAnyPerms ? {} : {
              OR: [
                { domainId: null },
                ...(domainId ? [{ domainId }] : [])
              ].filter(Boolean)
            }),
          },
          include: { children: true },
          orderBy: { order: 'asc' },
        })
        : [],
    ]);

    // 后续处理保持不变...
    const children = childrenData
      .map(({ descendant }) => descendant)
      .filter(Boolean)
      .map(formatToTermTreeData);
    const selfItems = selfData.map(formatToTermTreeData);
    return getUniqueItems([...children, ...selfItems], 'id');
  }

  async getParentSimpleTree(
    staff: UserProfile | null | undefined, // 允许 staff 为 null 或 undefined
    data: z.infer<typeof TermMethodSchema.getSimpleTree>,
  ) {
    // 安全解构 staff 属性并设置默认值
    const domainId = staff?.domainId ?? null;
    const permissions = staff?.permissions ?? [];

    // 权限判断逻辑（自动处理空权限数组）
    const hasAnyPerms =
      permissions.includes(RolePerms.READ_ANY_TERM) ||
      permissions.includes(RolePerms.MANAGE_ANY_TERM);

    const { termIds, taxonomyId } = data;

    // 构建通用权限过滤条件
    const buildDomainFilter = () => ({
      OR: [
        { domainId: null }, // 始终包含公共记录
        ...(domainId ? [{ domainId }] : []) // 动态添加域过滤
      ].filter(Boolean) // 确保数组有效性
    });

    const [parentData, selfData] = await Promise.all([
      db.termAncestry.findMany({
        where: {
          descendantId: { in: termIds },
          ancestor: {
            taxonomyId,
            // 应用动态权限过滤
            ...(hasAnyPerms ? {} : buildDomainFilter())
          }
        },
        include: {
          ancestor: {
            include: {
              children: true,
              parent: true
            }
          }
        },
        orderBy: { ancestor: { order: 'asc' } }
      }),
      db.term.findMany({
        where: {
          id: { in: termIds },
          taxonomyId,
          // 应用相同的权限过滤逻辑
          ...(hasAnyPerms ? {} : buildDomainFilter())
        },
        include: { children: true },
        orderBy: { order: 'asc' }
      })
    ]);

    // 数据处理保持不变...
    const parents = parentData
      .map(({ ancestor }) => ancestor)
      .filter(Boolean)
      .map(mapToTermSimpleTree);

    const selfItems = selfData.map(mapToTermSimpleTree);

    return getUniqueItems([...parents, ...selfItems], 'id');
  }
}
