import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ExpenseType } from '../entities/expense-type.entity';
import { CreateExpenseTypeDto, UpdateExpenseTypeDto } from './dto/expense-type.dto';

const DEFAULT_TYPES = [
  { code: 'water', name: '水费', category: 'room', sortOrder: 1 },
  { code: 'electricity', name: '电费', category: 'room', sortOrder: 2 },
  { code: 'cleaning', name: '保洁费', category: 'room', sortOrder: 3 },
  { code: 'damage', name: '损坏赔偿', category: 'both', sortOrder: 4 },
  { code: 'penalty', name: '罚款', category: 'personal', sortOrder: 5 },
  { code: 'key', name: '钥匙费', category: 'personal', sortOrder: 6 },
  { code: 'remote', name: '空调遥控器', category: 'personal', sortOrder: 7 },
  { code: 'deposit_deduction', name: '押金扣除', category: 'personal', sortOrder: 8 },
  { code: 'other', name: '其他', category: 'both', sortOrder: 99 },
];

@Injectable()
export class ExpenseTypesService {
  constructor(
    @InjectRepository(ExpenseType)
    private repo: Repository<ExpenseType>,
  ) {}

  async seedDefaults(): Promise<void> {
    for (const t of DEFAULT_TYPES) {
      const exists = await this.repo.findOne({ where: { code: t.code } });
      if (!exists) {
        await this.repo.save(this.repo.create(t));
      }
    }
  }

  async findAll(): Promise<ExpenseType[]> {
    return this.repo.find({ where: { enabled: true }, order: { sortOrder: 'ASC' } });
  }

  async findAllAdmin(): Promise<ExpenseType[]> {
    return this.repo.find({ order: { sortOrder: 'ASC' } });
  }

  async findOne(id: number): Promise<ExpenseType> {
    const t = await this.repo.findOne({ where: { id } });
    if (!t) throw new NotFoundException('费用类型不存在');
    return t;
  }

  async getValidCodes(): Promise<string[]> {
    const types = await this.findAll();
    return types.map((t) => t.code);
  }

  async create(dto: CreateExpenseTypeDto): Promise<ExpenseType> {
    const normalized = { ...dto, code: dto.code.trim(), name: dto.name.trim() };
    const exists = await this.repo.findOne({ where: { code: normalized.code } });
    if (exists) throw new ConflictException('费用类型代码已存在');
    return this.repo.save(this.repo.create(normalized));
  }

  async update(id: number, dto: UpdateExpenseTypeDto): Promise<ExpenseType> {
    const t = await this.findOne(id);
    Object.assign(t, dto, dto.name === undefined ? {} : { name: dto.name.trim() });
    return this.repo.save(t);
  }

  async remove(id: number): Promise<void> {
    const t = await this.findOne(id);
    if (!t.enabled) return;
    await this.repo.update(t.id, { enabled: false });
  }
}
