import { GenericCrudService } from '@d8d/shared-crud';
import { DataSource, Repository, Like, Not, In } from 'typeorm';
import { DisabledPerson } from '../entities/disabled-person.entity';
import { DisabledBankCard } from '../entities/disabled-bank-card.entity';
import { DisabledPhoto } from '../entities/disabled-photo.entity';
import { DisabledRemark } from '../entities/disabled-remark.entity';
import { DisabledVisit } from '../entities/disabled-visit.entity';
import { FileService, File } from '@d8d/file-module';
import { OrderPerson, OrderPersonAsset, EmploymentOrder } from '@d8d/allin-order-module';
import { WorkStatus, getWorkStatusLabel } from '@d8d/allin-enums';

// 前端专用的工作状态中文标签映射（与mini-ui保持一致）
const FrontendWorkStatusLabels: Record<WorkStatus, string> = {
  [WorkStatus.NOT_WORKING]: '未就业',
  [WorkStatus.PRE_WORKING]: '待入职',
  [WorkStatus.WORKING]: '在职',
  [WorkStatus.RESIGNED]: '离职'
};

export class DisabledPersonService extends GenericCrudService<DisabledPerson> {
  private readonly bankCardRepository: Repository<DisabledBankCard>;
  private readonly photoRepository: Repository<DisabledPhoto>;
  private readonly remarkRepository: Repository<DisabledRemark>;
  private readonly visitRepository: Repository<DisabledVisit>;
  private readonly fileRepository: Repository<File>;
  private fileService: FileService;

  constructor(dataSource: DataSource) {
    super(dataSource, DisabledPerson);
    this.bankCardRepository = dataSource.getRepository(DisabledBankCard);
    this.photoRepository = dataSource.getRepository(DisabledPhoto);
    this.remarkRepository = dataSource.getRepository(DisabledRemark);
    this.visitRepository = dataSource.getRepository(DisabledVisit);
    this.fileRepository = dataSource.getRepository(File);
    this.fileService = new FileService(dataSource);
  }

  /**
   * 创建残疾人 - 覆盖父类方法，添加身份证号唯一性检查
   */
  override async create(data: Partial<DisabledPerson>, userId?: string | number): Promise<DisabledPerson> {
    // 检查身份证号是否已存在
    if (data.idCard) {
      const existingPerson = await this.repository.findOne({
        where: { idCard: data.idCard }
      });
      if (existingPerson) {
        throw new Error('身份证号已存在');
      }
    }

    // 检查残疾证号是否已存在
    if (data.disabilityId) {
      const existingPerson = await this.repository.findOne({
        where: { disabilityId: data.disabilityId }
      });
      if (existingPerson) {
        throw new Error('残疾证号已存在');
      }
    }

    return super.create(data, userId);
  }

  /**
   * 更新残疾人 - 覆盖父类方法，添加身份证号唯一性检查
   */
  override async update(id: number, data: Partial<DisabledPerson>, userId?: string | number): Promise<DisabledPerson | null> {
    // 检查残疾人是否存在
    const person = await this.repository.findOne({ where: { id } });
    if (!person) {
      throw new Error('残疾人不存在');
    }

    // 检查身份证号是否与其他残疾人重复
    if (data.idCard && data.idCard !== person.idCard) {
      const existingPerson = await this.repository.findOne({
        where: { idCard: data.idCard, id: Not(id) }
      });
      if (existingPerson) {
        throw new Error('身份证号已存在');
      }
    }

    // 检查残疾证号是否与其他残疾人重复
    if (data.disabilityId && data.disabilityId !== person.disabilityId) {
      const existingPerson = await this.repository.findOne({
        where: { disabilityId: data.disabilityId, id: Not(id) }
      });
      if (existingPerson) {
        throw new Error('残疾证号已存在');
      }
    }

    return super.update(id, data, userId);
  }

  /**
   * 获取单个残疾人（包含关联数据）
   */
  async findOne(id: number): Promise<DisabledPerson | null> {
    const person = await this.repository.findOne({
      where: { id },
      relations: ['bankCards', 'bankCards.bankName', 'bankCards.file', 'bankCards.file.uploadUser', 'photos', 'photos.file', 'photos.file.uploadUser', 'remarks', 'visits']
    });

    if (person && person.photos) {
    }

    return person;
  }

  /**
   * 获取所有残疾人（分页+条件查询） - 返回源服务的格式
   */
  async findAll(query: {
    keyword?: string;
    bankNameId?: number;
    cardType?: string;
    disabilityType?: string;
    disabilityLevel?: string;
    province?: string;
    page?: number;
    limit?: number;
  }): Promise<{ data: DisabledPerson[], total: number }> {
    const {
      keyword,
      bankNameId,
      cardType,
      disabilityType,
      disabilityLevel,
      province,
      page = 1,
      limit = 10
    } = query;

    const queryBuilder = this.repository.createQueryBuilder('person');

    // 支持按关键词搜索（姓名或身份证号）
    if (keyword) {
      queryBuilder.andWhere('(person.name LIKE :keyword OR person.idCard LIKE :keyword)', {
        keyword: `%${keyword}%`
      });
    }

    if (disabilityType) {
      queryBuilder.andWhere('person.disabilityType = :disabilityType', { disabilityType });
    }
    if (disabilityLevel) {
      queryBuilder.andWhere('person.disabilityLevel = :disabilityLevel', { disabilityLevel });
    }
    if (province) {
      queryBuilder.andWhere('person.province = :province', { province });
    }

    // 处理银行卡相关筛选条件
    if (bankNameId || cardType) {
      queryBuilder.innerJoin('person.bankCards', 'bankCard');

      if (bankNameId) {
        queryBuilder.andWhere('bankCard.bankNameId = :bankNameId', { bankNameId });
      }
      if (cardType) {
        queryBuilder.andWhere('bankCard.cardType = :cardType', { cardType });
      }

      // 加载bankCards关系及其关联的bankName
      queryBuilder.leftJoinAndSelect('person.bankCards', 'bankCards')
                  .leftJoinAndSelect('bankCards.bankName', 'bankName');
    }

    const [data, total] = await queryBuilder
      .skip((page - 1) * limit)
      .take(limit)
      .orderBy('person.createTime', 'DESC')
      .getManyAndCount();

    // 加载关联数据
    if (data.length > 0) {
      const personIds = data.map(p => p.id);

      const [bankCards, photos, remarks, visits] = await Promise.all([
        this.bankCardRepository.find({ where: { personId: In(personIds) } }),
        this.photoRepository.find({
          where: { personId: In(personIds) },
          relations: ['file']
        }),
        this.remarkRepository.find({ where: { personId: In(personIds) } }),
        this.visitRepository.find({ where: { personId: In(personIds) } })
      ]);


      // 将关联数据分组到对应的残疾人
      const bankCardsMap = new Map<number, DisabledBankCard[]>();
      const photosMap = new Map<number, DisabledPhoto[]>();
      const remarksMap = new Map<number, DisabledRemark[]>();
      const visitsMap = new Map<number, DisabledVisit[]>();

      for (const card of bankCards) {
        const cards = bankCardsMap.get(card.personId) || [];
        cards.push(card);
        bankCardsMap.set(card.personId, cards);
      }

      for (const photo of photos) {
        const photos = photosMap.get(photo.personId) || [];
        photos.push(photo);
        photosMap.set(photo.personId, photos);
      }

      for (const remark of remarks) {
        const remarks = remarksMap.get(remark.personId) || [];
        remarks.push(remark);
        remarksMap.set(remark.personId, remarks);
      }

      for (const visit of visits) {
        const visits = visitsMap.get(visit.personId) || [];
        visits.push(visit);
        visitsMap.set(visit.personId, visits);
      }

      // 将关联数据附加到每个残疾人
      for (const person of data) {
        person.bankCards = bankCardsMap.get(person.id) || [];
        person.photos = photosMap.get(person.id) || [];
        person.remarks = remarksMap.get(person.id) || [];
        person.visits = visitsMap.get(person.id) || [];
      }
    }

    return { data, total };
  }

  /**
   * 根据身份证号查询残疾人
   */
  async findByIdCard(idCard: string): Promise<DisabledPerson | null> {
    const person = await this.repository.findOne({
      where: { idCard },
      relations: ['bankCards', 'photos', 'photos.file', 'remarks', 'visits']
    });

    if (person && person.photos) {
    }

    return person;
  }

  /**
   * 验证文件ID是否存在
   */
  async validateFileId(fileId: number): Promise<boolean> {
    try {
      const file = await this.fileRepository.findOne({ where: { id: fileId } });
      return !!file;
    } catch (error) {
      console.error('验证文件ID失败:', error);
      return false;
    }
  }

  /**
   * 创建照片记录（包含文件验证）
   */
  async createPhoto(photoData: Partial<DisabledPhoto>): Promise<DisabledPhoto> {
    // 验证文件ID是否存在
    if (photoData.fileId) {
      const fileExists = await this.validateFileId(photoData.fileId);
      if (!fileExists) {
        throw new Error('文件不存在');
      }
    } else {
      throw new Error('文件ID不能为空');
    }

    // 验证残疾人是否存在
    if (photoData.personId) {
      const personExists = await this.repository.findOne({ where: { id: photoData.personId } });
      if (!personExists) {
        throw new Error('残疾人不存在');
      }
    } else {
      throw new Error('残疾人ID不能为空');
    }

    const photo = this.photoRepository.create(photoData);
    return await this.photoRepository.save(photo);
  }

  /**
   * 批量创建照片记录
   */
  async createPhotosBatch(photosData: Partial<DisabledPhoto>[]): Promise<DisabledPhoto[]> {
    // 验证所有文件ID和残疾人ID
    for (const photoData of photosData) {
      if (photoData.fileId) {
        const fileExists = await this.validateFileId(photoData.fileId);
        if (!fileExists) {
          throw new Error(`文件ID ${photoData.fileId} 不存在`);
        }
      } else {
        throw new Error('文件ID不能为空');
      }

      if (photoData.personId) {
        const personExists = await this.repository.findOne({ where: { id: photoData.personId } });
        if (!personExists) {
          throw new Error(`残疾人ID ${photoData.personId} 不存在`);
        }
      } else {
        throw new Error('残疾人ID不能为空');
      }
    }

    const photos = this.photoRepository.create(photosData);
    return await this.photoRepository.save(photos);
  }

  /**
   * 批量创建残疾人
   */
  async batchCreate(persons: Partial<DisabledPerson>[]): Promise<{
    success: boolean;
    createdCount: number;
    failedItems: Array<{ index: number; error: string }>;
  }> {
    const failedItems: Array<{ index: number; error: string }> = [];
    let createdCount = 0;

    // 使用事务处理批量创建
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      for (let i = 0; i < persons.length; i++) {
        const personData = persons[i];
        if (personData === undefined) {
          failedItems.push({
            index: i,
            error: '数据为undefined'
          });
          continue;
        }
        try {
          // 检查身份证号是否已存在
          if (personData.idCard) {
            const existingPerson = await this.repository.findOne({
              where: { idCard: personData.idCard }
            });
            if (existingPerson) {
              throw new Error('身份证号已存在');
            }
          }

          // 检查残疾证号是否已存在
          if (personData.disabilityId) {
            const existingPerson = await this.repository.findOne({
              where: { disabilityId: personData.disabilityId }
            });
            if (existingPerson) {
              throw new Error('残疾证号已存在');
            }
          }

          // 创建残疾人
          const person = this.repository.create(personData);
          await queryRunner.manager.save(person);
          createdCount++;
        } catch (error) {
          failedItems.push({
            index: i,
            error: error instanceof Error ? error.message : '未知错误'
          });
        }
      }

      await queryRunner.commitTransaction();
      return {
        success: failedItems.length === 0,
        createdCount,
        failedItems
      };
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 获取人才工作历史
   */
  async getWorkHistory(personId: number): Promise<any[]> {
    const orderPersonRepo = this.dataSource.getRepository(OrderPerson);

    const workHistory = await orderPersonRepo.find({
      where: { personId },
      relations: ['order'],
      order: { joinDate: 'DESC' }
    });

    return workHistory.map(item => ({
      订单ID: item.orderId,
      订单名称: item.order?.orderName,
      入职日期: item.joinDate, // z.coerce.date().nullable()会自动转换
      实际入职日期: item.actualStartDate, // z.coerce.date().nullable()会自动转换
      离职日期: item.leaveDate, // z.coerce.date().nullable()会自动转换
      工作状态: FrontendWorkStatusLabels[item.workStatus] || getWorkStatusLabel(item.workStatus), // 使用前端专用映射，后备使用默认映射
      个人薪资: item.salaryDetail // z.coerce.number()会自动转换
    }));
  }

  /**
   * 获取人才薪资历史
   */
  async getSalaryHistory(personId: number): Promise<any[]> {
    const orderPersonRepo = this.dataSource.getRepository(OrderPerson);

    const salaryHistory = await orderPersonRepo.find({
      where: { personId },
      relations: ['order'],
      order: { joinDate: 'DESC' }
    });

    // 假设薪资详情存储在 salaryDetail 字段中
    // 这里可以根据实际业务逻辑解析薪资数据
    return salaryHistory.map(item => ({
      月份: item.joinDate, // z.coerce.date().nullable()会自动转换
      基本工资: item.salaryDetail, // z.coerce.number()会自动转换
      补贴: 0, // 需要根据业务逻辑计算
      扣款: 0, // 需要根据业务逻辑计算
      实发工资: item.salaryDetail // z.coerce.number()会自动转换
    }));
  }

  /**
   * 获取个人征信信息
   */
  async getCreditInfo(personId: number): Promise<any[]> {
    const bankCardRepo = this.dataSource.getRepository(DisabledBankCard);

    const bankCards = await bankCardRepo.find({
      where: { personId },
      relations: ['file']
    });

    return Promise.all(
      bankCards
        .filter(card => card.fileId) // 只返回有文件的记录
        .map(async (card) => ({
          文件ID: card.fileId ? card.fileId.toString() : '',
          文件URL: card.file ? await card.file.fullUrl : null,
          上传时间: card.file?.uploadTime, // z.coerce.date().nullable()会自动转换
          文件类型: card.file?.type,
          银行卡号: card.cardNumber,
          持卡人姓名: card.cardholderName,
          银行名称: card.bankNameId // 这里可能需要关联银行名称表
        }))
    );
  }

  /**
   * 获取个人关联视频
   */
  async getPersonVideos(personId: number): Promise<any[]> {
    const orderPersonAssetRepo = this.dataSource.getRepository(OrderPersonAsset);

    // 视频类型枚举值，根据 order-person-asset.entity.ts 中的定义
    const videoTypes = ['salary_video', 'tax_video', 'checkin_video', 'work_video'];

    const videos = await orderPersonAssetRepo.find({
      where: {
        personId,
        assetType: In(videoTypes)
      },
      relations: ['file']
    });

    return Promise.all(
      videos.map(async (video) => ({
        视频类型: video.assetType,
        文件ID: video.fileId ? video.fileId.toString() : '',
        文件URL: video.file ? await video.file.fullUrl : null,
        上传时间: video.file?.uploadTime, // z.coerce.date().nullable()会自动转换
        文件类型: video.file?.type,
        关联订单ID: video.orderId
      }))
    );
  }

  /**
   * 验证人员是否属于指定企业
   */
  async validatePersonBelongsToCompany(personId: number, companyId: number): Promise<boolean> {
    const orderPersonRepo = this.dataSource.getRepository(OrderPerson);

    // 查询人员是否通过订单关联到该企业
    const count = await orderPersonRepo.count({
      where: {
        personId,
        order: { companyId }
      }
    });

    return count > 0;
  }

  /**
   * 获取企业专用人才列表
   */
  async findAllForCompany(companyId: number, query: {
    search?: string;
    disabilityType?: string;
    jobStatus?: string;
    page?: number | string;
    limit?: number | string;
  }): Promise<{ data: any[], total: number }> {
    const {
      search,
      disabilityType,
      jobStatus,
      page = 1,
      limit = 10
    } = query;

    // 工作状态到中文标签的映射（使用前端专用映射）
    const workStatusLabelMap: Record<string, string> = FrontendWorkStatusLabels;

    // 确保page和limit是数字
    const pageNum = typeof page === 'string' ? parseInt(page, 10) || 1 : page || 1;
    const limitNum = typeof limit === 'string' ? parseInt(limit, 10) || 10 : limit || 10;

    const orderPersonRepo = this.dataSource.getRepository(OrderPerson);
    const queryBuilder = orderPersonRepo.createQueryBuilder('op')
      .innerJoinAndSelect('op.person', 'person')
      .innerJoinAndSelect('op.order', 'order')
      .where('order.companyId = :companyId', { companyId });

    // 支持按关键词搜索（姓名、身份证号、残疾证号）
    if (search) {
      queryBuilder.andWhere('(person.name LIKE :search OR person.idCard LIKE :search OR person.disabilityId LIKE :search)', {
        search: `%${search}%`
      });
    }

    if (disabilityType) {
      queryBuilder.andWhere('person.disabilityType = :disabilityType', { disabilityType });
    }

    if (jobStatus) {
      // 工作状态筛选逻辑 - 支持中文状态和WorkStatus枚举值
      // 映射中文状态到WorkStatus枚举值
      const chineseToWorkStatus: Record<string, WorkStatus> = {
        '在职': WorkStatus.WORKING,
        '待入职': WorkStatus.PRE_WORKING,
        '离职': WorkStatus.RESIGNED,
        '未就业': WorkStatus.NOT_WORKING
      };

      let workStatusValue: WorkStatus | undefined;

      // 检查是否是有效的WorkStatus枚举值
      if (Object.values(WorkStatus).includes(jobStatus as WorkStatus)) {
        workStatusValue = jobStatus as WorkStatus;
      } else if (chineseToWorkStatus[jobStatus]) {
        workStatusValue = chineseToWorkStatus[jobStatus];
      }

      if (workStatusValue) {
        // 使用order_person.work_status进行筛选
        queryBuilder.andWhere('op.workStatus = :workStatus', { workStatus: workStatusValue });
      }
    }

    // 按人员ID去重（同一人员可能关联多个订单），获取最新订单信息
    queryBuilder.select([
      'person.id as personId',
      'person.name as name',
      'person.gender as gender',
      'person.idCard as idCard',
      'person.disabilityType as disabilityType',
      'person.disabilityLevel as disabilityLevel',
      'person.phone as phone',
      'person.birth_date as birthDate',
      'MAX(op.joinDate) as latestJoinDate',
      'MAX(op.salary_detail) as salaryDetail',
      'MAX(op.workStatus) as workStatus', // 获取最新工作状态
      'order.orderName as orderName'
    ])
      .groupBy('person.id, person.name, person.gender, person.idCard, person.disabilityType, person.disabilityLevel, person.phone, person.birth_date, order.orderName');

    // 按最新入职日期排序
    queryBuilder.orderBy('latestJoinDate', 'DESC');

    // 获取总数
    const totalQuery = queryBuilder.clone();
    const total = await totalQuery.getCount();

    // 分页
    queryBuilder.offset((pageNum - 1) * limitNum).limit(limitNum);

    const rawResults = await queryBuilder.getRawMany();

    // 转换结果格式 - 注意：PostgreSQL列名是小写的
    const data = rawResults.map((row) => {
      const workStatus = row.workstatus as WorkStatus | undefined;
      const workStatusLabel = workStatus ? workStatusLabelMap[workStatus] : '未知状态';

      return {
        personId: row.personid,
        name: row.name,
        gender: row.gender,
        idCard: row.idcard,
        disabilityType: row.disabilitytype,
        disabilityLevel: row.disabilitylevel,
        phone: row.phone,
        jobStatus: workStatusLabel, // 保持字段名兼容性，使用中文标签
        workStatus: workStatus, // 新增：枚举值
        workStatusLabel: workStatusLabel, // 新增：中文标签
        birthDate: row.birthdate,
        salaryDetail: row.salarydetail,
        latestJoinDate: row.latestjoindate,
        orderName: row.ordername
      };
    });

    return { data, total };
  }

  /**
   * 获取企业专用人才详情
   */
  async findOneForCompany(personId: number, companyId: number): Promise<any | null> {
    // 首先验证人员是否属于该企业
    const isValid = await this.validatePersonBelongsToCompany(personId, companyId);
    if (!isValid) {
      return null;
    }

    // 工作状态到中文标签的映射（使用前端专用映射）
    const workStatusLabelMap: Record<string, string> = FrontendWorkStatusLabels;

    // 获取人员基本信息
    const person = await this.findOne(personId);
    if (!person) {
      return null;
    }

    // 获取薪资信息（从order_person表获取最新薪资）
    const orderPersonRepo = this.dataSource.getRepository(OrderPerson);
    const latestOrderPerson = await orderPersonRepo.createQueryBuilder('op')
      .innerJoinAndSelect('op.order', 'order')
      .where('op.personId = :personId', { personId })
      .andWhere('order.companyId = :companyId', { companyId })
      .orderBy('op.joinDate', 'DESC')
      .getOne();

    // 获取关联数据
    const [bankCards, photos] = await Promise.all([
      this.bankCardRepository.find({
        where: { personId },
        relations: ['bankName']
      }),
      this.photoRepository.find({
        where: { personId },
        relations: ['file']
      })
    ]);

    // 转换银行卡数据
    const formattedBankCards = bankCards.map(card => ({
      cardId: card.id,
      bankName: card.bankName?.name || '',
      cardNumber: card.cardNumber,
      isDefault: card.isDefault
    }));

    // 转换照片数据
    const formattedPhotos = await Promise.all(photos.map(async photo => ({
      fileId: photo.fileId,
      fileName: photo.file?.name || '',
      fileUrl: photo.file ? await photo.file.fullUrl : ''
    })));

    // 确定工作状态
    const workStatus = latestOrderPerson?.workStatus as WorkStatus | undefined;
    const workStatusLabel = workStatus ? workStatusLabelMap[workStatus] : '未知状态';

    return {
      personId: person.id,
      name: person.name,
      gender: person.gender,
      idCard: person.idCard,
      disabilityType: person.disabilityType,
      disabilityLevel: person.disabilityLevel,
      birthDate: person.birthDate,
      salaryDetail: latestOrderPerson?.salaryDetail || null,
      phone: person.phone,
      jobStatus: workStatusLabel, // 保持字段名兼容性，使用中文标签
      workStatus: workStatus, // 新增：枚举值
      workStatusLabel: workStatusLabel, // 新增：中文标签
      bankCards: formattedBankCards,
      photos: formattedPhotos
    };
  }
}