import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Not, Repository } from 'typeorm';
import { uuidV7 } from '../common/uuid-v7';
import { Organization } from '../entities/organization.entity';
import { Student } from '../entities/student.entity';
import { Occupancy } from '../entities/occupancy.entity';
import { ClassroomRental } from '../entities/classroom-rental.entity';
import { CreateOrganizationDto, UpdateOrganizationDto } from './dto/organization.dto';

const COLOR_PALETTE = [
  '#ff7875',
  '#ffa940',
  '#ffc53d',
  '#73d13d',
  '#36cfc9',
  '#40a9ff',
  '#597ef7',
  '#9254de',
  '#f759ab',
  '#8c8c8c',
];

@Injectable()
export class OrganizationsService {
  constructor(
    @InjectRepository(Organization) private repo: Repository<Organization>,
    @InjectRepository(Student) private studentRepo: Repository<Student>,
    @InjectRepository(Occupancy) private occupancyRepo: Repository<Occupancy>,
    @InjectRepository(ClassroomRental) private rentalRepo: Repository<ClassroomRental>,
  ) {}

  async findAll(query?: { includeArchived?: boolean; scope?: 'all' | 'host' | 'external' }) {
    const where: Record<string, unknown> = {};
    if (!query?.includeArchived) where.status = Not('archived');
    if (query?.scope === 'host') where.isHost = true;
    if (query?.scope === 'external') where.isHost = false;
    return this.repo.find({ where, order: { isHost: 'DESC', name: 'ASC' } });
  }

  async findOptions() {
    return this.repo.find({
      select: ['id', 'name', 'isHost'] as const,
      where: { status: 'active' },
      order: { isHost: 'DESC' as const, name: 'ASC' as const },
    });
  }

  async findOne(id: number) {
    const organization = await this.repo.findOne({ where: { id } });
    if (!organization) throw new NotFoundException('机构不存在');
    return organization;
  }

  async getHostOrganization() {
    const organization = await this.repo.findOne({ where: { isHost: true, status: 'active' } });
    if (!organization) throw new NotFoundException('尚未配置本机构');
    return organization;
  }

  async create(dto: CreateOrganizationDto) {
    if (dto.isHost) {
      const existingHost = await this.repo.findOne({ where: { isHost: true } });
      if (existingHost) throw new BadRequestException('本机构已存在，只能配置一个本机构');
    }
    const color = dto.color || COLOR_PALETTE[(await this.repo.count()) % COLOR_PALETTE.length];
    return this.repo.save(
      this.repo.create({
        ...dto,
        code: dto.code.trim().toUpperCase(),
        publicId: uuidV7(),
        color,
        isHost: dto.isHost ?? false,
        status: 'active',
      }),
    );
  }

  async update(id: number, dto: UpdateOrganizationDto) {
    const organization = await this.findOne(id);
    if (organization.isHost && dto.status === 'archived') {
      throw new BadRequestException('本机构不能归档');
    }
    await this.repo.update(id, {
      ...dto,
      ...(dto.code ? { code: dto.code.trim().toUpperCase() } : {}),
    });
    return this.repo.findOne({ where: { id } });
  }

  async remove(id: number) {
    const organization = await this.findOne(id);
    if (organization.isHost) throw new BadRequestException('本机构不能归档');
    await this.repo.update(id, { status: 'archived' });
    return { message: '已归档' };
  }

  async purge(id: number) {
    const organization = await this.findOne(id);
    if (organization.status !== 'archived') {
      throw new BadRequestException('仅已归档机构可以永久删除，请先归档');
    }
    if (organization.isHost) throw new BadRequestException('本机构不能永久删除');
    const [studentCount, occupancyCount, lessorCount, lesseeCount] = await Promise.all([
      this.studentRepo.count({ where: { organizationId: id } }),
      this.occupancyRepo.count({ where: { responsibleOrganizationId: id } }),
      this.rentalRepo.count({ where: { lessorOrganizationId: id } }),
      this.rentalRepo.count({ where: { lesseeOrganizationId: id } }),
    ]);
    const references: string[] = [];
    if (studentCount > 0) references.push('学生归属');
    if (occupancyCount > 0) references.push('入住责任机构');
    if (lessorCount > 0) references.push('出租租赁订单');
    if (lesseeCount > 0) references.push('承租租赁订单');
    if (references.length > 0) {
      throw new BadRequestException(`该机构存在关联数据（${references.join('、')}），无法永久删除`);
    }
    await this.repo.delete(id);
    return { message: '已永久删除机构（不可恢复）' };
  }
}
