import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';

export interface SellerScore {
    sellerId: string;
    sellerName: string;
    totalOrders: number;
    deliveredOrders: number;
    cancelledOrders: number;
    fulfillmentRate: number; // % of orders delivered
    avgRating: number;
    totalReviews: number;
    avgResponseTimeHours: number;
    totalSalesCents: number;
    performanceScore: number; // 0-100 composite score
}

@Injectable()
export class PerformanceService {
    constructor(private prisma: PrismaService) { }

    private calculateScore(metrics: {
        fulfillmentRate: number;
        avgRating: number;
        cancelRate: number;
    }): number {
        // Weighted score calculation
        // Fulfillment: 40%, Rating: 40%, Low cancellation: 20%
        const fulfillmentScore = metrics.fulfillmentRate * 40;
        const ratingScore = (metrics.avgRating / 5) * 40;
        const cancelScore = (1 - metrics.cancelRate) * 20;
        return Math.round(fulfillmentScore + ratingScore + cancelScore);
    }

    async getSellerScores(): Promise<SellerScore[]> {
        const sellers = await this.prisma.$queryRaw<any[]>`
            SELECT 
                c.id as seller_id,
                c.corporate_name as seller_name,
                COUNT(DISTINCT o.id) as total_orders,
                COUNT(DISTINCT CASE WHEN o.status = 'Entregue' THEN o.id END) as delivered_orders,
                COUNT(DISTINCT CASE WHEN o.status = 'Cancelado' THEN o.id END) as cancelled_orders,
                COALESCE(AVG(r.rating), 0)::float as avg_rating,
                COUNT(DISTINCT r.id) as total_reviews,
                COALESCE(SUM(o.total_cents), 0) as total_sales_cents
            FROM companies c
            LEFT JOIN orders o ON o.seller_id = c.id
            LEFT JOIN reviews r ON r.company_id = c.id
            WHERE c.category = 'distribuidora'
            GROUP BY c.id
            ORDER BY avg_rating DESC, total_orders DESC
        `;

        return sellers.map(s => {
            const totalOrders = Number(s.total_orders) || 1;
            const deliveredOrders = Number(s.delivered_orders);
            const cancelledOrders = Number(s.cancelled_orders);
            const fulfillmentRate = deliveredOrders / totalOrders;
            const cancelRate = cancelledOrders / totalOrders;
            const avgRating = Number(s.avg_rating) || 0;

            return {
                sellerId: s.seller_id,
                sellerName: s.seller_name,
                totalOrders: Number(s.total_orders),
                deliveredOrders,
                cancelledOrders,
                fulfillmentRate: Math.round(fulfillmentRate * 100),
                avgRating: Math.round(avgRating * 10) / 10,
                totalReviews: Number(s.total_reviews),
                avgResponseTimeHours: 24, // Placeholder - would need shipment timestamps
                totalSalesCents: Number(s.total_sales_cents),
                performanceScore: this.calculateScore({ fulfillmentRate, avgRating, cancelRate }),
            };
        });
    }

    async getSellerDetails(sellerId: string): Promise<SellerScore | null> {
        const scores = await this.getSellerScores();
        return scores.find(s => s.sellerId === sellerId) || null;
    }

    async getLeaderboard(): Promise<SellerScore[]> {
        const scores = await this.getSellerScores();
        return scores
            .sort((a, b) => b.performanceScore - a.performanceScore)
            .slice(0, 10);
    }
}
