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

export interface CreateAuctionDto {
  loanAccountId?: string; collateralType?: string; collateralDescription?: string;
  estimatedValue?: number; reservePrice?: number; auctionDate?: string; auctionDateBs?: string;
  venue?: string; publicationDetails?: string; officeId?: string; remarks?: string;
}
export type UpdateAuctionDto = Partial<CreateAuctionDto> & {
  auctionStatus?: string; finalSalePrice?: number; buyerName?: string; buyerPhone?: string; buyerAddress?: string;
};

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

  private async nextNumber(sub: string): Promise<string> {
    const r = await this.repo(sub);
    const count = await r.count();
    return `AUC-${String(count + 1).padStart(5, '0')}`;
  }

  async findAll(sub: string, opts: { auctionStatus?: string; q?: string; page?: number; limit?: number }) {
    const r = await this.repo(sub);
    const { auctionStatus, q, page = 1, limit = 20 } = opts;
    const qb = r.createQueryBuilder('a')
      .leftJoinAndSelect('a.loanAccount', 'loan')
      .where('a.deletedAt IS NULL')
      .orderBy('a.createdAt', 'DESC')
      .skip((page - 1) * limit).take(limit);
    if (auctionStatus) qb.andWhere('a.auctionStatus = :auctionStatus', { auctionStatus });
    if (q) qb.andWhere('(a.auctionNumber LIKE :q OR a.collateralDescription LIKE :q OR a.buyerName LIKE :q)', { q: `%${q}%` });
    const [items, total] = await qb.getManyAndCount();
    const summary = await this.summary(sub);
    return { items, total, page, limit, summary };
  }

  async summary(sub: string) {
    const r = await this.repo(sub);
    const [total, scheduled, completed, cancelled, noBidder] = await Promise.all([
      r.count(),
      r.count({ where: { auctionStatus: 'scheduled' } }),
      r.count({ where: { auctionStatus: 'completed' } }),
      r.count({ where: { auctionStatus: 'cancelled' } }),
      r.count({ where: { auctionStatus: 'no_bidder' } }),
    ]);
    return { total, scheduled, completed, cancelled, noBidder };
  }

  async findOne(sub: string, id: string) {
    const r = await this.repo(sub);
    const a = await r.findOne({ where: { id }, relations: ['loanAccount'] });
    if (!a) throw new NotFoundException('Auction not found');
    return a;
  }

  async create(sub: string, dto: CreateAuctionDto, userId?: string, userName?: string) {
    const r = await this.repo(sub);
    const auctionNumber = await this.nextNumber(sub);
    return r.save(r.create({ ...dto, auctionNumber, auctionStatus: 'scheduled', createdById: userId, createdByName: userName }));
  }

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

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