import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';
import { RobotLifecycleStage, PaymentDirection, PaymentStatus } from '@prisma/client';

@Injectable()
export class RobotReportService {
  private readonly logger = new Logger(RobotReportService.name);

  constructor(private readonly prisma: PrismaService) {}

  /**
   * 库存报告 — 按 v3 stage 聚合
   *
   * 物理在库 = WAREHOUSE_BRANDED_READY + WAREHOUSE_AT_W2 + WAREHOUSE_AT_W2_RLE + SALES_RESERVED
   * 可售     = WAREHOUSE_BRANDED_READY + WAREHOUSE_AT_W2_RLE
   * 在途     = LOGISTICS_IN_TRANSIT + LOGISTICS_BONDED + LOGISTICS_CUSTOMS_CLEARED
   */
  async getInventoryReport() {
    const stageCounts = await this.prisma.robotUnitSnapshot.groupBy({
      by: ['currentStage'],
      _count: true,
    });

    const countMap: Partial<Record<RobotLifecycleStage, number>> = {};
    for (const item of stageCounts) {
      countMap[item.currentStage] = item._count;
    }

    const inWarehouse =
      (countMap[RobotLifecycleStage.WAREHOUSE_BRANDED_READY] ?? 0) +
      (countMap[RobotLifecycleStage.WAREHOUSE_AT_W2] ?? 0) +
      (countMap[RobotLifecycleStage.WAREHOUSE_AT_W2_RLE] ?? 0) +
      (countMap[RobotLifecycleStage.SALES_RESERVED] ?? 0);
    const available =
      (countMap[RobotLifecycleStage.WAREHOUSE_BRANDED_READY] ?? 0) +
      (countMap[RobotLifecycleStage.WAREHOUSE_AT_W2_RLE] ?? 0);
    const inTransit =
      (countMap[RobotLifecycleStage.LOGISTICS_IN_TRANSIT] ?? 0) +
      (countMap[RobotLifecycleStage.LOGISTICS_BONDED] ?? 0) +
      (countMap[RobotLifecycleStage.LOGISTICS_CUSTOMS_CLEARED] ?? 0);

    return {
      byStage: countMap,
      inWarehouse,
      available,
      inTransit,
      total: stageCounts.reduce((sum, item) => sum + item._count, 0),
    };
  }

  /**
   * 销售报告 — 按 SalesOrder + DeliveryFulfillment 聚合
   */
  async getSalesReport() {
    const fulfillments = await this.prisma.deliveryFulfillment.findMany({
      where: { deletedAt: null },
      select: {
        cost: true,
        grossMargin: true,
        deliveredAt: true,
        deliveryRequest: {
          select: {
            customerId: true,
            salesOrder: {
              select: { totalAmount: true, currencyCode: true, customerId: true },
            },
          },
        },
      },
    });

    let totalRevenue = 0;
    const byCustomer: Record<string, { customerId: string; customerName?: string; count: number; revenue: number }> = {};
    // 月度趋势：YYYY-MM → { count, revenue }
    const byMonth: Record<string, { month: string; count: number; revenue: number }> = {};

    for (const f of fulfillments) {
      const customerId = f.deliveryRequest?.customerId ?? 'unknown';
      const revenue = Number(f.deliveryRequest?.salesOrder?.totalAmount ?? 0);
      totalRevenue += revenue;
      if (!byCustomer[customerId]) {
        byCustomer[customerId] = { customerId, count: 0, revenue: 0 };
      }
      byCustomer[customerId].count += 1;
      byCustomer[customerId].revenue += revenue;

      // 用 UTC 显式拼 YYYY-MM，避免 toISOString 在 server TZ ≠ UTC 时把月末
      // delivered 错算到下月（如北京时间 2026-05-31 23:00 = UTC 15:00 同月，
      // 但 toISOString 用 UTC 24h 边界，月末凌晨 delivered 可能跨月）
      const m = `${f.deliveredAt.getUTCFullYear()}-${String(f.deliveredAt.getUTCMonth() + 1).padStart(2, '0')}`;
      if (!byMonth[m]) byMonth[m] = { month: m, count: 0, revenue: 0 };
      byMonth[m].count += 1;
      byMonth[m].revenue += revenue;
    }

    // 跨 schema lookup customer names（@@relation 缺，单独查）
    const customerIds = Object.keys(byCustomer).filter((id) => id !== 'unknown');
    if (customerIds.length > 0) {
      const customers = await this.prisma.customer.findMany({
        where: { id: { in: customerIds } },
        select: { id: true, name: true, code: true },
      });
      for (const c of customers) {
        if (byCustomer[c.id]) byCustomer[c.id].customerName = c.name;
      }
    }

    const customerBreakdown = Object.values(byCustomer).sort((a, b) => b.revenue - a.revenue);
    const monthlyTrend = Object.values(byMonth).sort((a, b) => a.month.localeCompare(b.month));

    return {
      totalDelivered: fulfillments.length,
      totalRevenue,
      customerBreakdown,
      monthlyTrend,
    };
  }

  /**
   * 财务报告 — 收入/成本/毛利汇总
   */
  async getFinanceReport() {
    const [inboundAgg, outboundAgg, deliveryAgg] = await Promise.all([
      this.prisma.paymentRecord.aggregate({
        where: {
          deletedAt: null,
          direction: PaymentDirection.INBOUND,
          paymentStatus: PaymentStatus.PAID,
        },
        _sum: { amount: true },
        _count: true,
      }),
      this.prisma.paymentRecord.aggregate({
        where: {
          deletedAt: null,
          direction: PaymentDirection.OUTBOUND,
          paymentStatus: PaymentStatus.PAID,
        },
        _sum: { amount: true },
        _count: true,
      }),
      this.prisma.deliveryFulfillment.aggregate({
        where: { deletedAt: null },
        _sum: { cost: true, grossMargin: true },
        _count: true,
      }),
    ]);

    return {
      unitCount: deliveryAgg._count,
      revenue: Number(inboundAgg._sum.amount ?? 0),
      totalCost: Number(deliveryAgg._sum.cost ?? Number(outboundAgg._sum.amount ?? 0)),
      margin: Number(deliveryAgg._sum.grossMargin ?? 0),
    };
  }
}
