import type { ChatLogRecord, LeadRecord } from '@/lib/api';
import type { Lead } from '@/types';
import type { LeadBadge, LeadTag, LeadSource, Message, MessageSender, PipelineStage, SentimentLog } from '@/types/crm';

const TAG_MAP: Record<string, LeadTag> = {
  whale: '#CashBuyer',
  potential: '#Investor',
  hot: '#EndUser',
};

export function mapLeadRecordToStoreLead(record: LeadRecord): Lead {
  const qualification = record.qualification.toLowerCase() as Lead['qualification'];
  const status = record.stage === 'closed'
    ? 'closed'
    : record.stage === 'qualified' || record.stage === 'negotiation'
      ? 'qualified'
      : record.score >= 75
        ? 'hot'
        : record.stage === 'new'
          ? 'new'
          : 'engaged';
  const tags = Array.isArray(record.metadata?.tags) ? (record.metadata.tags as string[]) : [];
  return {
    id: record.id,
    name: record.name,
    phone: record.phone ?? '',
    source: mapSource(record.source),
    status,
    lastMessage: record.notes || 'No conversation summary yet.',
    lastActive: new Date(record.updated_at ?? record.created_at ?? Date.now()),
    unreadCount: 0,
    qualification: qualification === 'tire_kicker' || qualification === 'potential' || qualification === 'whale'
      ? qualification
      : 'potential',
    budget: record.budget,
    interest: record.unit_interest,
    quantumDynamicsScore: record.score,
    tags: tags.length > 0 ? tags : [record.qualification],
  };
}

export function mapLeadRecordToOracleLead(record: LeadRecord, chatLogs: ChatLogRecord[]): import('@/types/crm').Lead {
  const badge = mapBadge(record.qualification);
  const tags = mapOracleTags(record.qualification, record.metadata);
  return {
    id: record.id,
    name: record.name,
    phone: record.phone ?? '',
    stage: mapPipelineStage(record.stage),
    oracleScore: record.score,
    badge,
    tags,
    source: mapSource(record.source),
    budget: record.budget,
    unitInterest: record.unit_interest,
    profileImageUrl: `https://api.dicebear.com/9.x/glass/svg?seed=${encodeURIComponent(record.name)}`,
    visitedShowroom: record.stage === 'site_visit' || record.stage === 'negotiation' || record.stage === 'closed',
    inShowroomNow: record.stage === 'site_visit',
    messages: chatLogs.map(mapChatLogToOracleMessage),
    sentimentLog: buildSentimentLog(record.score, record.stage),
  };
}

function mapSource(source: string): LeadSource {
  if (source === 'walkin' || source === 'website' || source === 'whatsapp') return source;
  return 'website';
}

function mapPipelineStage(stage: string): PipelineStage {
  const normalized = stage.toLowerCase();
  if (normalized === 'new' || normalized === 'new_inquiries') return 'new_inquiries';
  if (normalized === 'qualified' || normalized === 'qualifying') return 'qualified';
  if (normalized === 'site_visit') return 'site_visit';
  if (normalized === 'negotiation') return 'negotiation';
  return 'closed';
}

function mapBadge(qualification: string): LeadBadge | undefined {
  const normalized = qualification.toLowerCase();
  if (normalized === 'whale') return 'whale';
  if (normalized === 'hot' || normalized === 'potential') return 'hot';
  if (normalized === 'tire_kicker') return 'tire_kicker';
  return undefined;
}

function mapOracleTags(qualification: string, metadata: Record<string, unknown>): LeadTag[] {
  const mapped = TAG_MAP[qualification.toLowerCase()];
  const rawTags = Array.isArray(metadata?.tags) ? metadata.tags as string[] : [];
  const canonical = rawTags.includes('#CashBuyer') || mapped === '#CashBuyer'
    ? '#CashBuyer'
    : rawTags.includes('#EndUser') || mapped === '#EndUser'
      ? '#EndUser'
      : '#Investor';
  return [canonical];
}

function mapChatLogToOracleMessage(log: ChatLogRecord): Message {
  return {
    id: log.id,
    sender: mapSender(log.sender),
    content: log.content,
    createdAt: log.created_at ?? new Date().toISOString(),
  };
}

function mapSender(sender: string): MessageSender {
  if (sender === 'lead' || sender === 'oracle' || sender === 'system') return sender;
  return 'system';
}

function buildSentimentLog(score: number, stage: string): SentimentLog[] {
  const base = Math.max(20, score - 18);
  const labels = stage === 'site_visit'
    ? ['Entry', 'Showroom peak', 'Pricing review']
    : ['Discovery', 'Qualification', 'Follow-up'];
  return labels.map((label, index) => ({
    id: `${stage}-${index}`,
    at: `${10 + index}:0${index}`,
    score: Math.min(100, base + index * 9),
    note: label,
  }));
}
