import { DataSource } from 'typeorm';
import { AreaEntityMt, AreaLevel } from './area.entity.mt';
import { DisabledStatus } from '@d8d/shared-types';

export class AreaServiceMt {
  private areaRepository;

  constructor(dataSource: DataSource) {
    this.areaRepository = dataSource.getRepository(AreaEntityMt);
  }

  /**
   * 获取指定租户的完整省市区树形结构
   */
  async getAreaTree(tenantId: number): Promise<AreaEntityMt[]> {
    const areas = await this.areaRepository.find({
      where: {
        tenantId,
        isDeleted: 0
      },
      order: {
        id: 'ASC',
        level: 'ASC',
        name: 'ASC',
      }
    });

    // 构建树形结构
    return this.buildTree(areas);
  }

  /**
   * 根据层级获取指定租户的树形结构
   */
  async getAreaTreeByLevel(tenantId: number, level: AreaLevel): Promise<AreaEntityMt[]> {
    const areas = await this.areaRepository.find({
      where: {
        tenantId,
        level,
        isDeleted: 0,
        isDisabled: DisabledStatus.ENABLED
      },
      relations: ['children'],
      order: {
        id: 'ASC',
        level: 'ASC',
        name: 'ASC'
      }
    });

    return areas;
  }

  /**
   * 获取指定租户和节点的子树
   */
  async getSubTree(tenantId: number, areaId: number): Promise<AreaEntityMt | null> {
    const area = await this.areaRepository.findOne({
      where: {
        tenantId,
        id: areaId,
        isDeleted: 0,
        isDisabled: DisabledStatus.ENABLED
      },
      relations: ['children'],
    });

    if (!area) return null;

    // 递归加载所有子节点
    await this.loadChildrenRecursively(tenantId, area);
    return area;
  }

  /**
   * 递归加载所有子节点
   */
  private async loadChildrenRecursively(tenantId: number, area: AreaEntityMt): Promise<void> {
    if (area.children && area.children.length > 0) {
      for (const child of area.children) {
        const fullChild = await this.areaRepository.findOne({
          where: {
            tenantId,
            id: child.id,
            isDeleted: 0,
            isDisabled: DisabledStatus.ENABLED
          },
          relations: ['children'],
        });

        if (fullChild) {
          child.children = fullChild.children;
          await this.loadChildrenRecursively(tenantId, child);
        }
      }
    }
  }

  /**
   * 构建树形结构
   */
  private buildTree(areas: AreaEntityMt[]): AreaEntityMt[] {
    const areaMap = new Map<number, AreaEntityMt>();
    const tree: AreaEntityMt[] = [];

    // 创建映射并初始化children数组
    areas.forEach(area => {
      const node = new AreaEntityMt({ ...area });
      node.children = [];
      areaMap.set(area.id, node);
    });

    // 构建树形结构
    areas.forEach(area => {
      const node = areaMap.get(area.id)!;
      if (area.parentId === null || area.parentId === 0) {
        tree.push(node);
      } else {
        const parent = areaMap.get(area.parentId);
        if (parent && parent.children) {
          parent.children.push(node);
        }
      }
    });

    return tree;
  }

  /**
   * 获取指定租户的区域路径（从根节点到当前节点）
   */
  async getAreaPath(tenantId: number, areaId: number): Promise<AreaEntityMt[]> {
    const path: AreaEntityMt[] = [];
    let currentArea = await this.areaRepository.findOne({
      where: {
        tenantId,
        id: areaId,
        isDeleted: 0,
        isDisabled: DisabledStatus.ENABLED
      }
    });

    while (currentArea) {
      path.unshift(currentArea);

      if (currentArea.parentId === null || currentArea.parentId === 0) {
        break;
      }

      currentArea = await this.areaRepository.findOne({
        where: {
          tenantId,
          id: currentArea.parentId,
          isDeleted: 0,
          isDisabled: DisabledStatus.ENABLED
        }
      });
    }

    return path;
  }

  /**
   * 获取指定租户的所有启用状态的省市区
   */
  async getEnabledAreas(tenantId: number): Promise<AreaEntityMt[]> {
    return this.areaRepository.find({
      where: {
        tenantId,
        isDeleted: 0,
        isDisabled: DisabledStatus.ENABLED
      },
      order: {
        id: 'ASC',
        level: 'ASC',
        name: 'ASC',
      }
    });
  }

  /**
   * 根据层级和父级ID获取指定租户的区域列表（高效查询）
   */
  async getAreasByLevelAndParent(tenantId: number, level: AreaLevel, parentId?: number): Promise<AreaEntityMt[]> {
    const where: any = {
      tenantId,
      level,
      isDeleted: 0,
      isDisabled: DisabledStatus.ENABLED
    };

    // 如果指定了父级ID，则添加父级条件
    if (parentId !== undefined) {
      where.parentId = parentId;
    }

    return this.areaRepository.find({
      where,
      order: {
        id: 'ASC',
        name: 'ASC'
      }
    });
  }

  /**
   * 创建区域（多租户版本）
   */
  async createArea(tenantId: number, areaData: Partial<AreaEntityMt>): Promise<AreaEntityMt> {
    const area = this.areaRepository.create({
      ...areaData,
      tenantId
    });
    return await this.areaRepository.save(area);
  }

  /**
   * 更新区域（多租户版本）
   */
  async updateArea(tenantId: number, areaId: number, updateData: Partial<AreaEntityMt>): Promise<AreaEntityMt | null> {
    const area = await this.areaRepository.findOne({
      where: { tenantId, id: areaId }
    });

    if (!area) return null;

    Object.assign(area, updateData);
    return await this.areaRepository.save(area);
  }

  /**
   * 删除区域（多租户版本）
   */
  async deleteArea(tenantId: number, areaId: number): Promise<boolean> {
    const result = await this.areaRepository.delete({
      tenantId,
      id: areaId
    });
    return result.affected !== 0;
  }

  /**
   * 获取区域详情（多租户版本）
   */
  async getAreaById(tenantId: number, areaId: number): Promise<AreaEntityMt | null> {
    return this.areaRepository.findOne({
      where: { tenantId, id: areaId }
    });
  }

  /**
   * 获取区域列表（多租户版本）
   */
  async getAreas(tenantId: number, options?: {
    keyword?: string;
    level?: AreaLevel;
    parentId?: number;
    page?: number;
    pageSize?: number;
  }): Promise<{ data: AreaEntityMt[]; total: number }> {
    const { keyword, level, parentId, page = 1, pageSize = 20 } = options || {};
    const skip = (page - 1) * pageSize;

    const where: any = { tenantId, isDeleted: 0 };

    if (keyword) {
      where.name = { $like: `%${keyword}%` };
    }

    if (level !== undefined) {
      where.level = level;
    }

    if (parentId !== undefined) {
      where.parentId = parentId;
    }

    const [data, total] = await this.areaRepository.findAndCount({
      where,
      skip,
      take: pageSize,
      order: {
        id: 'ASC',
        level: 'ASC',
        name: 'ASC'
      }
    });

    return { data, total };
  }
}