import { Injectable, NotFoundException } from '@nestjs/common';
import { TenantConnectionService } from '../../database/tenant-connection.service';
import { AdditionalWithholding } from '../../database/tenant/entities/additional-withholding.entity';
import { WithholdingKitta } from '../../database/tenant/entities/withholding-kitta.entity';
import { Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable()
export class AdditionalWithholdingService {
  constructor(
    private tenantConn: TenantConnectionService,
    @Inject(REQUEST) private request: Request,
  ) {}

  private sub() { return (this.request as any).tenantSubdomain as string; }
  private async ds() { return this.tenantConn.getTenantDataSource(this.sub()); }

  async list(q?: string, applicationId?: string, page = 1, limit = 20) {
    const ds = await this.ds();
    const r = ds.getRepository(AdditionalWithholding);
    const qb = r.createQueryBuilder('aw').where('aw.deletedAt IS NULL').orderBy('aw.createdAt', 'DESC');
    if (q) qb.andWhere('(aw.memberName LIKE :q OR aw.memberCode LIKE :q)', { q: `%${q}%` });
    if (applicationId) qb.andWhere('aw.applicationId = :applicationId', { applicationId });
    const total = await qb.getCount();
    const items = await qb.skip((page - 1) * limit).take(limit).getMany();
    return { items, total, page, limit };
  }

  async findOne(id: string) {
    const ds = await this.ds();
    const e = await ds.getRepository(AdditionalWithholding).findOne({ where: { id } });
    if (!e) throw new NotFoundException('Withholding not found');
    const kittas = await ds.getRepository(WithholdingKitta).find({ where: { withholdingId: id } });
    return { ...e, kittas };
  }

  async create(dto: any) {
    const ds = await this.ds();
    const r = ds.getRepository(AdditionalWithholding);
    const { kittas, ...rest } = dto;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const wh = (await r.save(r.create({ ...rest, status: rest.status ?? 'active' }) as any)) as unknown as AdditionalWithholding;
    if (kittas && Array.isArray(kittas)) {
      const kr = ds.getRepository(WithholdingKitta);
      for (const k of kittas) {
        await kr.save(kr.create({ ...k, withholdingId: wh.id }) as any);
      }
    }
    return this.findOne(wh.id);
  }

  async update(id: string, dto: any) {
    const ds = await this.ds();
    const r = ds.getRepository(AdditionalWithholding);
    const e = await r.findOne({ where: { id } });
    if (!e) throw new NotFoundException();
    const { kittas, ...rest } = dto;
    await r.save(Object.assign(e, rest));
    if (kittas !== undefined) {
      const kr = ds.getRepository(WithholdingKitta);
      await kr.delete({ withholdingId: id });
      if (Array.isArray(kittas)) {
        for (const k of kittas) {
          await kr.save(kr.create({ ...k, withholdingId: id }) as any);
        }
      }
    }
    return this.findOne(id);
  }

  async remove(id: string) {
    const ds = await this.ds();
    await ds.getRepository(AdditionalWithholding).softDelete(id);
    return { id };
  }
}
