/**
 * Lead Scoring Service
 *
 * Calculates lead scores based on:
 * - Company/contact data quality (0-25 points)
 * - Topic/industry relevance (0-25 points)
 * - Engagement level (0-25 points)
 * - Demo/conversion status (0-25 points)
 *
 * Total score: 0-100
 * Hot: >80, Warm: 50-80, Cold: <50
 */

import { prisma } from '@/lib/db';
import { contactSubmissionsAdapter } from '@/lib/adapters/contacts';

// Lead score breakdown interface
export interface LeadScoreBreakdown {
  dataQuality: number; // 0-25 (completeness of profile data)
  topicRelevance: number; // 0-25 (how relevant their topic/needs are)
  engagement: number; // 0-25 (form completion, message quality)
  conversionSignal: number; // 0-25 (demo attendance, status)
}

// Complete lead score result
export interface LeadScore {
  total: number; // 0-100
  breakdown: LeadScoreBreakdown;
  tier: 'hot' | 'warm' | 'cold';
  updatedAt: Date;
}

// Topic/industry scoring (healthcare-related gets highest due to target market)
const TOPIC_SCORES: Record<string, number> = {
  // High-value topics
  'demo-request': 25,
  partnership: 23,
  enterprise: 22,
  integration: 20,
  pricing: 20,
  // Medium-value topics
  general: 15,
  support: 12,
  feedback: 10,
  // Lower-value
  other: 8,
  unknown: 5,
};

/**
 * Calculate lead score for a demo booking
 */
export async function calculateDemoLeadScore(demoId: string): Promise<LeadScore> {
  const demo = await prisma.demo_bookings.findUnique({
    where: { id: demoId },
    select: {
      id: true,
      fullName: true,
      email: true,
      telephone: true,
      specialRequirements: true,
      status: true,
      createdAt: true,
      contactedAt: true,
    },
  });

  if (!demo) {
    throw new Error(`Demo booking not found: ${demoId}`);
  }

  // Calculate data quality score (completeness)
  let dataQuality = 10; // Base score for submitting demo form
  if (demo.fullName && demo.fullName.length > 2) dataQuality += 5;
  if (demo.email) dataQuality += 5;
  if (demo.telephone) dataQuality += 3;
  if (demo.specialRequirements) dataQuality += 2;
  dataQuality = Math.min(dataQuality, 25);

  // Topic relevance - demo requests are high-intent
  const topicRelevance = 25; // Requesting a demo is highest intent

  // Engagement score
  let engagement = 15; // Completed demo booking form
  if (demo.specialRequirements && demo.specialRequirements.length > 20) {
    engagement += 5; // Detailed requirements shows high engagement
  }
  if (demo.contactedAt) {
    engagement += 5; // Has been followed up
  }
  engagement = Math.min(engagement, 25);

  // Conversion signal based on status
  let conversionSignal = 0;
  if (demo.status === 'confirmed') {
    conversionSignal = 25; // Confirmed/attended demo
  } else if (demo.status === 'pending') {
    conversionSignal = 15; // Scheduled but not yet attended
  } else if (demo.status === 'cancelled') {
    conversionSignal = 0; // Cancelled
  }

  const total = dataQuality + topicRelevance + engagement + conversionSignal;
  const tier = total > 80 ? 'hot' : total >= 50 ? 'warm' : 'cold';

  return {
    total,
    breakdown: {
      dataQuality,
      topicRelevance,
      engagement,
      conversionSignal,
    },
    tier,
    updatedAt: new Date(),
  };
}

/**
 * Calculate lead score for a contact submission
 */
export async function calculateContactLeadScore(contactId: string): Promise<LeadScore> {
  const contact = await contactSubmissionsAdapter.findUnique({
    where: { id: contactId },
    select: {
      id: true,
      name: true,
      email: true,
      phone: true,
      company: true,
      topic: true,
      message: true,
      status: true,
      created_at: true,
      resolved_at: true,
    },
  });

  if (!contact) {
    throw new Error(`Contact submission not found: ${contactId}`);
  }

  // Calculate data quality score
  let dataQuality = 5; // Base score for submitting form
  if (contact.name && contact.name.length > 2) dataQuality += 5;
  if (contact.email) dataQuality += 5;
  if (contact.phone) dataQuality += 3;
  if (contact.company) dataQuality += 7; // Company info is valuable
  dataQuality = Math.min(dataQuality, 25);

  // Topic relevance
  const topicKey = (contact.topic || 'unknown').toLowerCase().replace(/\s+/g, '-');
  const topicRelevance = TOPIC_SCORES[topicKey] ?? TOPIC_SCORES.unknown;

  // Engagement - based on message quality
  let engagement = 5; // Submitted contact form
  if (contact.message) {
    const wordCount = contact.message.split(/\s+/).length;
    if (wordCount > 50) engagement += 15;
    else if (wordCount > 20) engagement += 10;
    else if (wordCount > 10) engagement += 5;

    // Check for high-intent keywords
    const messageLower = contact.message.toLowerCase();
    if (
      messageLower.includes('demo') ||
      messageLower.includes('pricing') ||
      messageLower.includes('trial') ||
      messageLower.includes('enterprise')
    ) {
      engagement += 5;
    }
  }
  engagement = Math.min(engagement, 25);

  // Conversion signal - contacts haven't demoed yet
  let conversionSignal = 0;
  if (contact.status === 'resolved' || contact.resolved_at) {
    conversionSignal = 10; // Has been responded to
  } else if (contact.status === 'in-progress') {
    conversionSignal = 5; // Being worked on
  }

  const total = dataQuality + topicRelevance + engagement + conversionSignal;
  const tier = total > 80 ? 'hot' : total >= 50 ? 'warm' : 'cold';

  return {
    total,
    breakdown: {
      dataQuality,
      topicRelevance,
      engagement,
      conversionSignal,
    },
    tier,
    updatedAt: new Date(),
  };
}

/**
 * Calculate lead score for a user (based on their profile data)
 */
export async function calculateUserLeadScore(userId: string): Promise<LeadScore> {
  const user = await prisma.users.findUnique({
    where: { id: userId },
    select: {
      id: true,
      name: true,
      email: true,
      companyName: true,
      companySize: true,
      industry: true,
      phoneNumber: true,
      onboardingComplete: true,
      emailVerified: true,
      stripeCustomerId: true,
      subscriptions: {
        select: {
          status: true,
        },
        take: 1,
      },
    },
  });

  if (!user) {
    throw new Error(`User not found: ${userId}`);
  }

  // Calculate data quality score
  let dataQuality = 5; // Base score for having an account
  if (user.name) dataQuality += 3;
  if (user.email) dataQuality += 3;
  if (user.companyName) dataQuality += 5;
  if (user.companySize) dataQuality += 4;
  if (user.industry) dataQuality += 3;
  if (user.phoneNumber) dataQuality += 2;
  dataQuality = Math.min(dataQuality, 25);

  // Topic relevance - based on industry
  let topicRelevance = 10; // Default
  const industryLower = (user.industry || '').toLowerCase();
  if (
    industryLower.includes('healthcare') ||
    industryLower.includes('medical') ||
    industryLower.includes('clinic') ||
    industryLower.includes('hospital')
  ) {
    topicRelevance = 25;
  } else if (
    industryLower.includes('dental') ||
    industryLower.includes('beauty') ||
    industryLower.includes('wellness')
  ) {
    topicRelevance = 20;
  }

  // Engagement score
  let engagement = 0;
  if (user.emailVerified) engagement += 10;
  if (user.onboardingComplete) engagement += 10;
  if (user.stripeCustomerId) engagement += 5; // Has payment info
  engagement = Math.min(engagement, 25);

  // Conversion signal based on subscription
  let conversionSignal = 0;
  if (user.subscriptions.length > 0) {
    const sub = user.subscriptions[0];
    if (sub.status === 'active') {
      conversionSignal = 25; // Converted customer
    } else if (sub.status === 'trialing') {
      conversionSignal = 20; // In trial
    } else if (sub.status === 'canceled') {
      conversionSignal = 5; // Churned
    }
  }

  const total = dataQuality + topicRelevance + engagement + conversionSignal;
  const tier = total > 80 ? 'hot' : total >= 50 ? 'warm' : 'cold';

  return {
    total,
    breakdown: {
      dataQuality,
      topicRelevance,
      engagement,
      conversionSignal,
    },
    tier,
    updatedAt: new Date(),
  };
}

/**
 * Batch calculate lead scores for all demo bookings
 */
export async function calculateAllDemoLeadScores(): Promise<Map<string, LeadScore>> {
  const demos = await prisma.demo_bookings.findMany({
    select: {
      id: true,
      fullName: true,
      telephone: true,
      specialRequirements: true,
      status: true,
      contactedAt: true,
    },
  });

  const scores = new Map<string, LeadScore>();

  for (const demo of demos) {
    // Data quality
    let dataQuality = 10;
    if (demo.fullName && demo.fullName.length > 2) dataQuality += 5;
    if (demo.telephone) dataQuality += 3;
    if (demo.specialRequirements) dataQuality += 2;
    dataQuality = Math.min(dataQuality, 25);

    // Topic - demos are high intent
    const topicRelevance = 25;

    // Engagement
    let engagement = 15;
    if (demo.specialRequirements && demo.specialRequirements.length > 20) {
      engagement += 5;
    }
    if (demo.contactedAt) engagement += 5;
    engagement = Math.min(engagement, 25);

    // Conversion signal
    let conversionSignal = 0;
    if (demo.status === 'confirmed') {
      conversionSignal = 25;
    } else if (demo.status === 'pending') {
      conversionSignal = 15;
    }

    const total = dataQuality + topicRelevance + engagement + conversionSignal;
    const tier = total > 80 ? 'hot' : total >= 50 ? 'warm' : 'cold';

    scores.set(demo.id, {
      total,
      breakdown: { dataQuality, topicRelevance, engagement, conversionSignal },
      tier,
      updatedAt: new Date(),
    });
  }

  return scores;
}

/**
 * Batch calculate lead scores for all contact submissions
 */
export async function calculateAllContactLeadScores(): Promise<Map<string, LeadScore>> {
  const contacts = await contactSubmissionsAdapter.findMany({
    select: {
      id: true,
      name: true,
      phone: true,
      company: true,
      topic: true,
      message: true,
      status: true,
      resolved_at: true,
    },
  });

  const scores = new Map<string, LeadScore>();

  for (const contact of contacts) {
    // Data quality
    let dataQuality = 5;
    if (contact.name && contact.name.length > 2) dataQuality += 5;
    if (contact.phone) dataQuality += 3;
    if (contact.company) dataQuality += 7;
    dataQuality = Math.min(dataQuality, 25);

    // Topic relevance
    const topicKey = (contact.topic || 'unknown').toLowerCase().replace(/\s+/g, '-');
    const topicRelevance = TOPIC_SCORES[topicKey] ?? TOPIC_SCORES.unknown;

    // Engagement
    let engagement = 5;
    if (contact.message) {
      const wordCount = contact.message.split(/\s+/).length;
      if (wordCount > 50) engagement += 15;
      else if (wordCount > 20) engagement += 10;
      else if (wordCount > 10) engagement += 5;
    }
    engagement = Math.min(engagement, 25);

    // Conversion signal
    let conversionSignal = 0;
    if (contact.status === 'resolved' || contact.resolved_at) {
      conversionSignal = 10;
    } else if (contact.status === 'in-progress') {
      conversionSignal = 5;
    }

    const total = dataQuality + topicRelevance + engagement + conversionSignal;
    const tier = total > 80 ? 'hot' : total >= 50 ? 'warm' : 'cold';

    scores.set(contact.id, {
      total,
      breakdown: { dataQuality, topicRelevance, engagement, conversionSignal },
      tier,
      updatedAt: new Date(),
    });
  }

  return scores;
}

/**
 * Get lead score tier label and color
 */
export function getLeadScoreDisplay(score: number): {
  tier: 'hot' | 'warm' | 'cold';
  label: string;
  color: string;
  bgColor: string;
} {
  if (score > 80) {
    return {
      tier: 'hot',
      label: 'Hot Lead',
      color: 'text-red-600',
      bgColor: 'bg-red-100',
    };
  } else if (score >= 50) {
    return {
      tier: 'warm',
      label: 'Warm Lead',
      color: 'text-orange-600',
      bgColor: 'bg-orange-100',
    };
  } else {
    return {
      tier: 'cold',
      label: 'Cold Lead',
      color: 'text-blue-600',
      bgColor: 'bg-blue-100',
    };
  }
}
