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

export interface FraudAlert {
    id: string;
    companyId: string;
    companyName: string;
    alertType: string;
    severity: 'low' | 'medium' | 'high' | 'critical';
    description: string;
    evidence: Record<string, unknown>;
    status: 'active' | 'dismissed' | 'confirmed';
    createdAt: Date;
}

export interface FraudAnalysis {
    companyId: string;
    riskScore: number; // 0-100
    flags: string[];
    metrics: {
        unusualPricingPattern: boolean;
        highCancellationRate: boolean;
        rapidAccountChanges: boolean;
        abnormalOrderVolume: boolean;
        suspiciousBehaviour: boolean;
    };
}

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

    async getAlerts(): Promise<FraudAlert[]> {
        // For now, run analysis on all sellers and generate alerts
        const suspiciousSellers = await this.prisma.$queryRaw<any[]>`
            SELECT 
                c.id as company_id,
                c.corporate_name as company_name,
                COUNT(DISTINCT CASE WHEN o.status = 'Cancelado' THEN o.id END)::float / 
                    NULLIF(COUNT(DISTINCT o.id), 0) as cancel_rate,
                COUNT(DISTINCT o.id) as order_count
            FROM companies c
            LEFT JOIN orders o ON o.seller_id = c.id
            WHERE c.category = 'distribuidora'
            GROUP BY c.id
            HAVING COUNT(DISTINCT CASE WHEN o.status = 'Cancelado' THEN o.id END)::float / 
                   NULLIF(COUNT(DISTINCT o.id), 0) > 0.3
               OR COUNT(DISTINCT o.id) < 5
        `;

        return suspiciousSellers.map((s, index) => ({
            id: `alert-${index}`,
            companyId: s.company_id,
            companyName: s.company_name,
            alertType: s.cancel_rate > 0.3 ? 'high_cancellation_rate' : 'low_order_volume',
            severity: s.cancel_rate > 0.5 ? 'high' : 'medium',
            description: s.cancel_rate > 0.3
                ? `Alta taxa de cancelamento: ${Math.round((s.cancel_rate || 0) * 100)}%`
                : `Baixo volume de pedidos: ${s.order_count} pedidos`,
            evidence: {
                cancelRate: s.cancel_rate,
                orderCount: Number(s.order_count),
            },
            status: 'active' as const,
            createdAt: new Date(),
        }));
    }

    async analyzeCompany(companyId: string): Promise<FraudAnalysis> {
        const company = await this.prisma.$queryRaw<any[]>`
            SELECT 
                c.id,
                c.corporate_name,
                COUNT(DISTINCT o.id) as total_orders,
                COUNT(DISTINCT CASE WHEN o.status = 'Cancelado' THEN o.id END) as cancelled_orders,
                STDDEV(o.total_cents) as price_stddev,
                AVG(o.total_cents) as avg_order_value
            FROM companies c
            LEFT JOIN orders o ON o.seller_id = c.id
            WHERE c.id = ${companyId}::uuid
            GROUP BY c.id
        `;

        if (!company[0]) {
            return {
                companyId,
                riskScore: 0,
                flags: ['Company not found'],
                metrics: {
                    unusualPricingPattern: false,
                    highCancellationRate: false,
                    rapidAccountChanges: false,
                    abnormalOrderVolume: false,
                    suspiciousBehaviour: false,
                },
            };
        }

        const c = company[0];
        const cancelRate = Number(c.cancelled_orders) / (Number(c.total_orders) || 1);
        const priceStddev = Number(c.price_stddev) || 0;
        const avgOrderValue = Number(c.avg_order_value) || 0;

        const flags: string[] = [];
        let riskScore = 0;

        // Check for high cancellation rate
        const highCancellationRate = cancelRate > 0.2;
        if (highCancellationRate) {
            flags.push(`Taxa de cancelamento alta: ${Math.round(cancelRate * 100)}%`);
            riskScore += 30;
        }

        // Check for unusual pricing pattern
        const unusualPricingPattern = priceStddev > avgOrderValue * 2;
        if (unusualPricingPattern) {
            flags.push('Variação de preços suspeita');
            riskScore += 20;
        }

        // Check for abnormal order volume (too few orders)
        const abnormalOrderVolume = Number(c.total_orders) < 5 && Number(c.total_orders) > 0;
        if (abnormalOrderVolume) {
            flags.push('Volume de pedidos muito baixo');
            riskScore += 10;
        }

        return {
            companyId,
            riskScore: Math.min(riskScore, 100),
            flags,
            metrics: {
                unusualPricingPattern,
                highCancellationRate,
                rapidAccountChanges: false, // Would need login history
                abnormalOrderVolume,
                suspiciousBehaviour: riskScore > 50,
            },
        };
    }

    async dismissAlert(alertId: string, reason: string): Promise<{ status: string }> {
        // In production, this would update a fraud_alerts table
        console.log(`Dismissing alert ${alertId}: ${reason}`);
        return { status: 'dismissed' };
    }

    async confirmAlert(alertId: string, data: { action: string; notes: string }): Promise<{ status: string }> {
        // In production, this would update the company status and log the action
        console.log(`Confirming alert ${alertId}: action=${data.action}, notes=${data.notes}`);
        return { status: 'confirmed' };
    }
}
