import { Injectable, NotFoundException } from '@nestjs/common';
import { TenantConnectionService } from '../../database/tenant-connection.service';
import { CreditRenew } from '../../database/tenant/entities/credit-renew.entity';

export interface CreateCreditRenewDto {
  loanAccountId: string;
  memberId?: string;
  memberName: string;
  officeId?: string;
  renewAmount?: number;
  renewAmountWords?: string;
  interestRate?: number;
  loanPeriod?: string;
  loanPeriodType?: string;
  decisionDate?: string;
  decisionDateBs?: string;
  paymentAmount?: number;
  paymentAmountWords?: string;
  paymentType?: string;
  newMaturityDate?: string;
  newMaturityDateBs?: string;
  remarks?: string;
}
export type UpdateCreditRenewDto = Partial<CreateCreditRenewDto> & { status?: string };

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

  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('c')
      .where('c.deletedAt IS NULL')
      .orderBy('c.createdAt', 'DESC')
      .skip((page - 1) * limit)
      .take(limit);
    if (status) qb.andWhere('c.status = :status', { status });
    if (loanAccountId) qb.andWhere('c.loanAccountId = :loanAccountId', { loanAccountId });
    if (q) qb.andWhere('(c.memberName 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 c = await r.findOne({ where: { id } });
    if (!c) throw new NotFoundException('Credit renew record not found');
    return c;
  }

  async create(sub: string, dto: CreateCreditRenewDto, 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: UpdateCreditRenewDto) {
    const r = await this.repo(sub);
    const c = await this.findOne(sub, id);
    Object.assign(c, dto);
    return r.save(c);
  }

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