import { Injectable } from '@nestjs/common';
import { DeliveryStatus } from '@prisma/client';
import { PrismaService } from '../database/prisma.service';
import { FinanceService } from '../finance/finance.service';

@Injectable()
export class AdminService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly financeService: FinanceService,
  ) {}

  async getOverview() {
    const [financeDashboard, restaurantsSummary, recentOrders, restaurants, deliveries] = await Promise.all([
      this.financeService.getDashboard(),
      this.financeService.getRestaurantsSummary(),
      this.prisma.order.findMany({
        take: 12,
        orderBy: { createdAt: 'desc' },
        include: {
          customer: true,
          restaurant: true,
          payment: true,
          delivery: true,
        },
      }),
      this.prisma.restaurant.findMany(),
      this.prisma.delivery.findMany({
        where: { status: { in: [DeliveryStatus.ASSIGNED, DeliveryStatus.ACCEPTED, DeliveryStatus.PICKED_UP, DeliveryStatus.ON_THE_WAY] } },
      }),
    ]);

    const topRestaurants = [...restaurantsSummary]
      .sort((a, b) => b.customerGross - a.customerGross)
      .slice(0, 5)
      .map((restaurant) => ({
        id: restaurant.id,
        name: restaurant.name,
        status: restaurant.status,
        orderCount: restaurant.orderCount,
        customerGross: restaurant.customerGross,
        totalSold: restaurant.totalSold,
        commissionAmount: restaurant.commissionAmount,
        platformNet: restaurant.platformNet,
        driverPayoutTotal: restaurant.driverPayoutTotal,
        payoutToRestaurant: restaurant.payoutToRestaurant,
        availablePayoutAmount: restaurant.availablePayoutAmount ?? 0,
        pendingPayoutAmount: restaurant.pendingPayoutAmount ?? 0,
        nextPayoutDate: restaurant.nextPayoutDate,
        commissionPercentage: restaurant.commissionPercentage,
      }));

    const salesByStatus = recentOrders.reduce<Record<string, number>>((acc, order) => {
      acc[order.status] = (acc[order.status] ?? 0) + 1;
      return acc;
    }, {});

    return {
      finance: financeDashboard,
      operations: {
        activeOrders: recentOrders.filter((order) => !['DELIVERED', 'CANCELLED', 'REFUNDED'].includes(order.status)).length,
        restaurantsOnline: restaurants.filter((restaurant) => restaurant.isOpen && !restaurant.isPaused).length,
        activeDeliveries: deliveries.length,
        totalRestaurants: restaurants.length,
        salesByStatus,
      },
      topRestaurants,
      recentOrders: recentOrders.map((order) => ({
        id: order.id,
        createdAt: order.createdAt,
        status: order.status,
        total: Number(order.total),
        paymentStatus: order.payment?.status ?? null,
        restaurant: order.restaurant.name,
        customer: order.customer.fullName,
        deliveryStatus: order.delivery?.status ?? null,
      })),
    };
  }

  async getLiveMap() {
    const [drivers, deliveries, restaurants] = await Promise.all([
      this.prisma.driver.findMany({ include: { locations: { orderBy: { createdAt: 'desc' }, take: 1 } } }),
      this.prisma.delivery.findMany({
        where: { status: { in: [DeliveryStatus.ASSIGNED, DeliveryStatus.ACCEPTED, DeliveryStatus.PICKED_UP, DeliveryStatus.ON_THE_WAY] } },
        include: { order: { include: { restaurant: true, address: true } }, driver: true },
      }),
      this.prisma.restaurant.findMany({ where: { isOpen: true } }),
    ]);

    return {
      city: 'Operacao ao vivo',
      drivers: {
        online: drivers.filter((driver) => driver.isOnline).length,
        offline: drivers.filter((driver) => !driver.isOnline).length,
        busy: deliveries.filter((delivery) => Boolean(delivery.driverId)).length,
        markers: drivers.map((driver) => ({ id: driver.id, name: driver.fullName, isOnline: driver.isOnline, latestLocation: driver.locations[0] ?? null })),
      },
      activeOrders: deliveries.length,
      restaurants: restaurants.map((restaurant) => ({ id: restaurant.id, name: restaurant.name, latitude: restaurant.latitude, longitude: restaurant.longitude, city: restaurant.city, neighborhood: restaurant.neighborhood })),
      routes: deliveries.map((delivery) => ({
        deliveryId: delivery.id,
        orderId: delivery.orderId,
        driverId: delivery.driverId,
        status: delivery.status,
        restaurant: {
          name: delivery.order.restaurant.name,
          latitude: delivery.order.restaurant.latitude,
          longitude: delivery.order.restaurant.longitude,
        },
        customer: {
          latitude: delivery.order.address?.latitude,
          longitude: delivery.order.address?.longitude,
        },
        etaMinutes: delivery.etaMinutes,
      })),
    };
  }

  getDeliverySettings() {
    return this.financeService.getDeliverySettings();
  }

  updateDeliverySettings(body: Record<string, unknown>) {
    return this.financeService.updateDeliverySettings(body);
  }
}
