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

export interface CreateBlacklistDto {
  memberId: string;
  memberName: string;
  applicationId?: string;
  officeId?: string;
  debtType?: string;
  outstandingAmount?: number;
  blacklistDate?: string;
  blacklistDateBs?: string;
  newspaperPublication?: string;
  remarks?: string;
}

export interface UpdateBlacklistDto {
  blacklistStatus?: string;
  debtType?: string;
  outstandingAmount?: number;
  whitelistDate?: string;
  whitelistDateBs?: string;
  newspaperPublication?: string;
  remarks?: string;
}

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

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

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

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

  async whitelist(sub: string, id: string, dto: { whitelistDate?: string; whitelistDateBs?: string; remarks?: string }) {
    const r = await this.repo(sub);
    const b = await this.findOne(sub, id);
    b.blacklistStatus = 'whitelisted';
    b.whitelistDate = dto.whitelistDate;
    b.whitelistDateBs = dto.whitelistDateBs;
    if (dto.remarks) b.remarks = dto.remarks;
    return r.save(b);
  }

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