import { Injectable, NotFoundException } from '@nestjs/common';
import { TenantConnectionService } from '../../database/tenant-connection.service';
import { TaketaPatra } from '../../database/tenant/entities/taketa-patra.entity';

export interface CreateTaketaPatraDto {
  loanAccountId: string;
  memberId?: string;
  memberName: string;
  officeId?: string;
  type?: string;
  letterType?: string;
  capitalAmount?: number;
  interestAmount?: number;
  penaltyAmount?: number;
  totalAmount?: number;
  totalAmountWords?: string;
  loanTitle?: string;
  loanPurpose?: string;
  lastInstallmentDate?: string;
  lastInstallmentDateBs?: string;
  paymentDeadline?: string;
  paymentDeadlineBs?: string;
  noticeDateBs?: string;
  writerBy?: string;
  reviewBy?: string;
  approvedBy?: string;
  remarks?: string;
}
export type UpdateTaketaPatraDto = Partial<CreateTaketaPatraDto> & { status?: string };

@Injectable()
export class TaketaPatrasService {
  constructor(private tenantConn: TenantConnectionService) {}
  private async repo(sub: string) {
    const ds = await this.tenantConn.getTenantDataSource(sub);
    return ds.getRepository(TaketaPatra);
  }

  async findAll(sub: string, opts: { status?: string; loanAccountId?: string; q?: string; page?: number; limit?: number }) {
    const r = await this.repo(sub);
    const { status, loanAccountId, q, page = 1, limit = 20 } = opts;
    const qb = r.createQueryBuilder('t')
      .where('t.deletedAt IS NULL')
      .orderBy('t.createdAt', 'DESC')
      .skip((page - 1) * limit)
      .take(limit);
    if (status) qb.andWhere('t.status = :status', { status });
    if (loanAccountId) qb.andWhere('t.loanAccountId = :loanAccountId', { loanAccountId });
    if (q) qb.andWhere('(t.memberName LIKE :q OR t.letterType 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 t = await r.findOne({ where: { id } });
    if (!t) throw new NotFoundException('Taketa patra not found');
    return t;
  }

  async create(sub: string, dto: CreateTaketaPatraDto, userId?: string, userName?: string) {
    const r = await this.repo(sub);
    return r.save(r.create({ ...(dto as any), status: 'draft', createdById: userId, createdByName: userName }));
  }

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

  async remove(sub: string, id: string) {
    const r = await this.repo(sub);
    const t = await this.findOne(sub, id);
    t.deletedAt = new Date();
    await r.save(t);
    return { ok: true };
  }
}
