import { Injectable, NotFoundException } from '@nestjs/common';
import { TenantConnectionService } from '../../database/tenant-connection.service';
import { DartaChalani } from '../../database/tenant/entities/darta-chalani.entity';
import { CreateDartaChalaniDto, UpdateDartaChalaniDto } from './darta-chalani.dto';
import { Like, IsNull } from 'typeorm';

@Injectable()
export class DartaChalaniService {
  constructor(private tenantConn: TenantConnectionService) {}

  private async repo(sub: string) {
    const ds = await this.tenantConn.getTenantDataSource(sub);
    return ds.getRepository(DartaChalani);
  }

  async findAll(sub: string, opts: { type?: string; q?: string; page?: number; limit?: number }) {
    const r = await this.repo(sub);
    const { type, q, page = 1, limit = 20 } = opts;
    const qb = r.createQueryBuilder('d')
      .leftJoinAndSelect('d.office', 'office')
      .where('d.deletedAt IS NULL')
      .orderBy('d.createdAt', 'DESC')
      .skip((page - 1) * limit)
      .take(limit);

    if (type) qb.andWhere('d.type = :type', { type });
    if (q) {
      qb.andWhere(
        '(d.subject LIKE :q OR d.regNumber LIKE :q OR d.partyName LIKE :q OR d.partyOffice LIKE :q)',
        { q: `%${q}%` },
      );
    }

    const [items, total] = await qb.getManyAndCount();
    return { items, total, page, limit };
  }

  async findOne(sub: string, id: string) {
    const r = await this.repo(sub);
    const d = await r.findOne({ where: { id }, relations: ['office'] });
    if (!d) throw new NotFoundException('Darta/Chalani record not found');
    return d;
  }

  async nextRegNumber(sub: string, type: string, fiscalYear: string) {
    const r = await this.repo(sub);
    const last = await r.findOne({
      where: { type, fiscalYear },
      order: { createdAt: 'DESC' },
    });
    if (!last?.regNumber) return '1';
    const num = parseInt(last.regNumber, 10);
    return isNaN(num) ? '1' : String(num + 1);
  }

  async create(sub: string, dto: CreateDartaChalaniDto, createdBy?: string) {
    const r = await this.repo(sub);

    // Auto assign reg number if not provided
    let regNumber = dto.regNumber;
    if (!regNumber && dto.fiscalYear) {
      regNumber = await this.nextRegNumber(sub, dto.type, dto.fiscalYear);
    }

    const d = r.create({ ...dto, regNumber, active: true, createdBy });
    return r.save(d);
  }

  async update(sub: string, id: string, dto: UpdateDartaChalaniDto, updatedBy?: string) {
    const r = await this.repo(sub);
    const d = await this.findOne(sub, id);
    Object.assign(d, { ...dto, updatedBy });
    return r.save(d);
  }

  async remove(sub: string, id: string) {
    const r = await this.repo(sub);
    const d = await this.findOne(sub, id);
    await r.softRemove(d);
    return { ok: true };
  }
}
