// apps/api/src/services/score.service.js

const { SCORING_WEIGHTS, SCORE_THRESHOLDS } = require('../../../../packages/shared/constants');
const { DatabaseClient } = require('../../../../packages/db/client');

const db = new DatabaseClient();

class ScoreService {
    calculateScore(lead) {
        let score = 0;
        let breakdown = {};
        
        const weights = SCORING_WEIGHTS || { freshness: 25, clarity: 25, contact: 25, urgency: 25 };
        const thresholds = SCORE_THRESHOLDS || { HOT: 70, WARM: 40 };

        // Freshness score (newer = better)
        const freshnessScore = this.calculateFreshnessScore(lead.freshness || lead.created_at || lead.timestamp);
        score += freshnessScore * (weights.freshness / 100);
        breakdown.freshness = freshnessScore * (weights.freshness / 100);
        
        // Clarity score
        const textPayload = lead.text || `${lead.title || ''} ${lead.description || ''}`.trim();
        const clarityScore = this.calculateClarityScore(lead.clarity, textPayload);
        score += clarityScore * (weights.clarity / 100);
        breakdown.clarity = clarityScore * (weights.clarity / 100);
        
        // Contact availability score
        const hasContactInfo = !!(lead.hasContact || lead.emails?.length || lead.phones?.length);
        const contactScore = hasContactInfo ? 100 : 0;
        score += contactScore * (weights.contact / 100);
        breakdown.contact = contactScore * (weights.contact / 100);
        
        // Urgency score
        const urgencyScore = this.calculateUrgencyScore(lead.urgency);
        score += urgencyScore * (weights.urgency / 100);
        breakdown.urgency = urgencyScore * (weights.urgency / 100);
        
        // Determine category matching threshold parameters
        let category;
        if (score >= thresholds.HOT) {
            category = 'hot';
        } else if (score >= thresholds.WARM) {
            category = 'warm';
        } else {
            category = 'cold';
        }
        
        return {
            score: Math.round(score),
            category,
            breakdown
        };
    }
    
    calculateFreshnessScore(date) {
        if (!date) return 50;
        
        const now = new Date();
        const ageInHours = (now - new Date(date)) / (1000 * 60 * 60);
        
        if (ageInHours < 24) return 100;
        if (ageInHours < 48) return 80;
        if (ageInHours < 72) return 60;
        if (ageInHours < 168) return 40; // 7 days
        if (ageInHours < 720) return 20; // 30 days
        return 10;
    }
    
    calculateClarityScore(clarity, text) {
        if (clarity === 'high') return 100;
        if (clarity === 'medium') return 60;
        
        if (!text) return 30;
        
        let score = 0;
        
        // Payload evaluation checks
        if (text.length > 200) score += 30;
        else if (text.length > 100) score += 20;
        else if (text.length > 50) score += 10;
        
        if (text.toLowerCase().includes('location') || text.match(/in\s+[A-Z][a-z]+/)) score += 20;
        if (text.toLowerCase().includes('budget') || text.toLowerCase().includes('price')) score += 20;
        if (text.toLowerCase().includes('contact') || text.match(/@|phone|whatsapp/i)) score += 30;
        
        return Math.min(100, score);
    }
    
    calculateUrgencyScore(urgency) {
        if (urgency === 'high') return 100;
        if (urgency === 'medium') return 60;
        return 20;
    }
    
    async recalcScore(leadId) {
        const [lead] = await db.query('SELECT * FROM leads WHERE id = ?', [leadId]);
        if (!lead) return null;

        const evaluation = this.calculateScore(lead);
        await db.run(
            'UPDATE leads SET score = ?, score_category = ? WHERE id = ?',
            [evaluation.score, evaluation.category, leadId]
        );
        return evaluation;
    }
    
    async bulkRecalc() {
        const leads = await db.query('SELECT * FROM leads');
        let count = 0;
        for (const lead of leads) {
            const evaluation = this.calculateScore(lead);
            await db.run(
                'UPDATE leads SET score = ?, score_category = ? WHERE id = ?',
                [evaluation.score, evaluation.category, lead.id]
            );
            count++;
        }
        console.log(`Successfully completed bulk score recalculation for ${count} leads.`);
        return count;
    }
}

module.exports = new ScoreService();