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

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

  // --- Commission groups ---
  @Get('groups')
  async groups() {
    const m = await getMerchant(this.prisma);
    const list = await this.prisma.commissionGroup.findMany({
      where: { merchantId: m.id },
      orderBy: { createdAt: 'desc' },
      include: { _count: { select: { affiliates: true } } },
    });
    return list.map((g) => ({
      id: g.id,
      name: g.name,
      type: g.type,
      value: Number(g.value),
      tiers: g.tiers ?? null,
      signupBonus: g.signupBonus == null ? null : Number(g.signupBonus),
      targetSales: g.targetSales,
      targetBonus: g.targetBonus == null ? null : Number(g.targetBonus),
      members: g._count.affiliates,
    }));
  }

  @Post('groups')
  async createGroup(@Body() body: Record<string, any>) {
    const m = await getMerchant(this.prisma);
    const g = await this.prisma.commissionGroup.create({
      data: {
        merchantId: m.id,
        name: body.name || 'New Group',
        type: (body.type as any) || 'PERCENT',
        value: Number(body.value ?? 0),
        tiers: body.tiers ?? undefined,
        signupBonus:
          body.signupBonus === '' || body.signupBonus == null ? null : Number(body.signupBonus),
        targetSales:
          body.targetSales === '' || body.targetSales == null ? null : Number(body.targetSales),
        targetBonus:
          body.targetBonus === '' || body.targetBonus == null ? null : Number(body.targetBonus),
      },
    });
    return { ok: true, id: g.id };
  }

  @Put('groups/:id')
  async updateGroup(@Param('id') id: string, @Body() body: Record<string, any>) {
    const num = (v: any) => (v === '' || v == null ? null : Number(v));
    const data: any = {};
    if (body.name !== undefined) data.name = body.name;
    if (body.type !== undefined) data.type = body.type;
    if (body.value !== undefined) data.value = Number(body.value);
    if (body.signupBonus !== undefined) data.signupBonus = num(body.signupBonus);
    if (body.targetSales !== undefined) data.targetSales = num(body.targetSales);
    if (body.targetBonus !== undefined) data.targetBonus = num(body.targetBonus);
    await this.prisma.commissionGroup.update({ where: { id }, data });
    return { ok: true };
  }

  @Delete('groups/:id')
  async deleteGroup(@Param('id') id: string) {
    await this.prisma.affiliate.updateMany({ where: { groupId: id }, data: { groupId: null } });
    await this.prisma.commissionGroup.delete({ where: { id } });
    return { ok: true };
  }

  // --- Product commissions (PRD 4.4) ---
  @Get('product-commissions')
  async productCommissions() {
    const m = await getMerchant(this.prisma);
    const [rows, affiliates] = await Promise.all([
      this.prisma.productCommission.findMany({ where: { merchantId: m.id }, orderBy: { createdAt: 'desc' } }),
      this.prisma.affiliate.findMany({ where: { merchantId: m.id }, select: { id: true, name: true } }),
    ]);
    const nameById = new Map(affiliates.map((a) => [a.id, a.name]));
    return {
      rows: rows.map((r) => ({
        id: r.id,
        matchType: r.matchType,
        matchValue: r.matchValue,
        affiliateId: r.affiliateId,
        affiliateName: r.affiliateId ? nameById.get(r.affiliateId) ?? '—' : 'All affiliates',
        commissionType: r.commissionType,
        commissionValue: Number(r.commissionValue),
      })),
      affiliates: affiliates.map((a) => ({ id: a.id, name: a.name })),
    };
  }

  @Post('product-commissions')
  async createProductCommission(@Body() body: Record<string, any>) {
    const m = await getMerchant(this.prisma);
    if (!body.matchValue?.trim()) throw new BadRequestException('Enter a product keyword or tag');
    const r = await this.prisma.productCommission.create({
      data: {
        merchantId: m.id,
        matchType: body.matchType === 'TAG' ? 'TAG' : 'PRODUCT',
        matchValue: String(body.matchValue).trim(),
        affiliateId: body.affiliateId || null,
        commissionType: body.commissionType === 'FLAT' ? 'FLAT' : 'PERCENT',
        commissionValue: Number(body.commissionValue) || 0,
      },
    });
    return { ok: true, id: r.id };
  }

  @Delete('product-commissions/:id')
  async deleteProductCommission(@Param('id') id: string) {
    await this.prisma.productCommission.delete({ where: { id } });
    return { ok: true };
  }
}
