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';

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);
  }

  /**
   * 创建残疾人 - 覆盖父类方法，添加身份证号唯一性检查
   */
  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);
  }

  /**
   * 更新残疾人 - 覆盖父类方法，添加身份证号唯一性检查
   */
  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.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];
        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();
    }
  }
}