import { Controller, Get, Param, Post, Query } from '@nestjs/common';
import { PrismaService } from '../common/prisma.service';
import { getMerchant } from '../common/core';

@Controller('admin')
export class SalesController {
  constructor(private prisma: PrismaService) {}

  // --- Sales (PRD 4.7) + refund handling (PRD 4.4) ---
  @Get('sales')
  async sales(
    @Query('status') status?: string,
    @Query('from') from?: string,
    @Query('to') to?: string,
    @Query('affiliateId') affiliateId?: string,
  ) {
    const m = await getMerchant(this.prisma);
    const where: any = { merchantId: m.id };
    if (status) where.status = status;
    if (affiliateId) where.affiliateId = affiliateId;
    if (from || to) {
      where.createdAt = {};
      if (from) where.createdAt.gte = new Date(from);
      if (to) {
        const d = new Date(to);
        d.setHours(23, 59, 59, 999);
        where.createdAt.lte = d;
      }
    }
    const orders = await this.prisma.referralOrder.findMany({
      where,
      orderBy: { createdAt: 'desc' },
      include: { affiliate: { select: { name: true } } },
    });
    return orders.map((o) => ({
      id: o.id,
      orderId: o.shopifyOrderId,
      affiliate: o.affiliate.name,
      date: o.createdAt.toISOString().slice(0, 10),
      total: Number(o.total),
      commission: Number(o.commission),
      via: o.attribution,
      status: o.status,
    }));
  }

  /** Reverse or re-apply a sale's commission to keep balances consistent. */
  private async setSaleStatus(id: string, status: 'APPROVED' | 'REJECTED' | 'REFUNDED') {
    const o = await this.prisma.referralOrder.findUnique({ where: { id } });
    if (!o) return { ok: false };
    const counted = o.status === 'APPROVED' || o.status === 'PENDING';
    const willCount = status === 'APPROVED';
    const ops: any[] = [
      this.prisma.referralOrder.update({
        where: { id },
        data: { status, refundedAt: status === 'REFUNDED' ? new Date() : null },
      }),
    ];
    if (counted && !willCount) ops.push(this.prisma.affiliate.update({ where: { id: o.affiliateId }, data: { balance: { decrement: o.commission } } }));
    if (!counted && willCount) ops.push(this.prisma.affiliate.update({ where: { id: o.affiliateId }, data: { balance: { increment: o.commission } } }));
    await this.prisma.$transaction(ops);
    return { ok: true };
  }

  @Post('sales/:id/approve')
  async approveSale(@Param('id') id: string) {
    return this.setSaleStatus(id, 'APPROVED');
  }
  @Post('sales/:id/reject')
  async rejectSale(@Param('id') id: string) {
    return this.setSaleStatus(id, 'REJECTED');
  }
  @Post('sales/:id/refund')
  async refundSale(@Param('id') id: string) {
    return this.setSaleStatus(id, 'REFUNDED');
  }
}
