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

  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 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: '已归档' };
  }
}
