import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/shared/lib/apiClient';
import { stableArray, unwrapObject } from '@/shared/lib/apiShape';

/**
 * useClient360 — fetch unified client entity
 * Feeds: CRM lead data + QD score + pipeline stage + contact info
 */
export function useClient360(personId: string) {
  const query = useQuery({
    queryKey: ['client360', personId],
    queryFn:  async () => {
      const payload = await api.get<unknown>(`/crm/client-360/${personId}`);
      return mapClient360(normalizeSnapshot(payload));
    },
    staleTime: 30_000,
    enabled:  !!personId,
  });
  return { client: query.data, isLoading: query.isLoading, error: query.error };
}

/**
 * useConversations — unified comms feed for a lead
 */
export function useConversations(personId: string) {
  const qc = useQueryClient();
  const query = useQuery({
    queryKey: ['conversations', personId],
    queryFn: async () => {
      const payload = await api.get<unknown>(`/crm/client-360/${personId}`);
      return mapConversationEvents(normalizeSnapshot(payload));
    },
    staleTime: 10_000,
    enabled:  !!personId,
  });

  const sendWhatsApp = (text: string) =>
    api.post(`/comms/send`, { person_id: personId, channel: 'whatsapp', text })
       .then(() => qc.invalidateQueries({ queryKey: ['conversations', personId] }));

  return { events: query.data ?? [], isLoading: query.isLoading, sendWhatsApp };
}

/**
 * useClientProperties — linked property interests
 */
export function useClientProperties(personId: string) {
  const query = useQuery({
    queryKey: ['client-properties', personId],
    queryFn: async () => {
      const payload = await api.get<unknown>(`/crm/client-360/${personId}`);
      return mapPropertyInterests(normalizeSnapshot(payload));
    },
    staleTime: 60_000,
    enabled:  !!personId,
  });
  return { properties: query.data ?? [], isLoading: query.isLoading };
}

/**
 * useClientTasks — tasks for a specific lead
 */
export function useClientTasks(personId: string) {
  const qc = useQueryClient();
  const query = useQuery({
    queryKey: ['client-tasks', personId],
    queryFn: async () => {
      const payload = await api.get<unknown>(`/crm/client-360/${personId}`);
      return mapTasks(normalizeSnapshot(payload));
    },
    staleTime: 30_000,
    enabled:  !!personId,
  });

  const markDone = (taskId: string) =>
    api.patch(`/crm/tasks/${taskId}`, { status: 'done' })
       .then(() => qc.invalidateQueries({ queryKey: ['client-tasks', personId] }));

  const snooze = (taskId: string) =>
    api.patch(`/crm/tasks/${taskId}`, { status: 'snoozed' })
       .then(() => qc.invalidateQueries({ queryKey: ['client-tasks', personId] }));

  // Group tasks
  const all = query.data ?? [];
  const tasks = all.map(t => ({
    ...t,
    group: t.status === 'done' ? 'completed'
         : t.isDueToday         ? 'today'
         : 'upcoming',
  })) as any[];

  return { tasks, isLoading: query.isLoading, markDone, snooze };
}

// ── Types ────────────────────────────────────────────────────
export interface Client360Data {
  id: string;
  name: string;
  location?: string;
  primaryPhone?: string;
  avatarUrl?: string;
  qdScore: number;
  qdDelta: number;
  stageName: string;
  stageEmoji: string;
  lastContactRelative: string;
  lastContactChannel: string;
  aiInsight?: string;
  extractedFacts?: Record<string, string>;
  objections?: string[];
  qdHistory?: { date: string; score: number; label?: string }[];
}

interface ConversationEvent {
  id: string;
  type: 'whatsapp' | 'call' | 'email';
  timestamp: string;
  timestampRelative: string;
  messages?: { sender: 'client' | 'you'; text: string; status?: '✓' | '✓✓' }[];
  duration?: string;
  direction?: 'inbound' | 'outbound';
  keyMoments?: string[];
  hasTranscript?: boolean;
  subject?: string;
}

interface PropertyInterest {
  id: string;
  projectName: string;
  unitName: string;
  config: string;
  area: string;
  price: string;
  thumbnailUrl?: string;
  isPrimary: boolean;
  engagementLevel: 'High' | 'Medium' | 'Low';
}

interface Task {
  id: string;
  label: string;
  dueAt?: string;
  status: 'pending' | 'done' | 'snoozed';
  isDueToday?: boolean;
  isAIGenerated?: boolean;
}

interface Client360Snapshot {
  client_ref?: string;
  identity?: {
    person_id?: string;
    full_name?: string;
    primary_phone?: string | null;
    primary_email?: string | null;
    buyer_type?: string | null;
    persona_labels?: string[];
  };
  current_lead?: {
    status?: string | null;
    budget_band?: string | null;
    urgency?: string | null;
    objections?: string[];
    motivations?: string[];
  };
  active_opportunities?: Array<{
    opportunity_id?: string;
    stage?: string | null;
    value?: number | null;
    probability?: number | null;
    expected_close_date?: string | null;
    next_action?: string | null;
  }>;
  recent_interactions?: Array<{
    interaction_id?: string;
    channel?: string | null;
    interaction_type?: string | null;
    happened_at?: string | null;
    summary?: string | null;
  }>;
  property_interests?: Array<{
    interest_id?: string;
    project_name?: string | null;
    unit_preference?: string | null;
    configuration?: string | null;
    budget_min?: number | null;
    budget_max?: number | null;
    priority?: number | null;
  }>;
  tasks?: Array<{
    reminder_id?: string;
    title?: string | null;
    notes?: string | null;
    due_at?: string | null;
    status?: string | null;
    created_by_type?: string | null;
  }>;
  qd_overview?: Record<string, { current_value?: number | null; computed_at?: string | null; reasoning?: string | null }>;
  risk_flags?: string[];
  recommended_next_actions?: string[];
}

function normalizeSnapshot(payload: unknown): Client360Snapshot {
  const snapshot = unwrapObject<Client360Snapshot>(payload);
  if (!snapshot) return {};
  return {
    ...snapshot,
    identity: snapshot.identity ?? {},
    current_lead: snapshot.current_lead ?? {},
    active_opportunities: stableArray(snapshot.active_opportunities),
    recent_interactions: stableArray(snapshot.recent_interactions),
    property_interests: stableArray(snapshot.property_interests),
    tasks: stableArray(snapshot.tasks),
    risk_flags: stableArray(snapshot.risk_flags),
    recommended_next_actions: stableArray(snapshot.recommended_next_actions),
  };
}

function scoreToPercent(value: number | null | undefined): number {
  const safe = Number(value ?? 0);
  const pct = safe <= 1 ? safe * 100 : safe;
  return Math.max(0, Math.min(100, Math.round(pct)));
}

function bestQdScore(snapshot: Client360Snapshot): number {
  const qd = snapshot.qd_overview ?? {};
  const preferred = qd.intent_score ?? qd.engagement_score ?? qd.financial_qualification;
  if (preferred?.current_value != null) return scoreToPercent(preferred.current_value);
  const first = Object.values(qd).find((item) => item?.current_value != null);
  return scoreToPercent(first?.current_value);
}

function stageLabel(status?: string | null): string {
  return (status || 'new').replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
}

function stageEmoji(status?: string | null): string {
  if (!status) return 'N';
  return status.slice(0, 1).toUpperCase();
}

function relativeDate(value?: string | null): string {
  if (!value) return 'No contact yet';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return 'Recently';
  const diffMs = Date.now() - date.getTime();
  const days = Math.floor(diffMs / 86_400_000);
  if (days > 0) return `${days}d ago`;
  const hours = Math.floor(diffMs / 3_600_000);
  if (hours > 0) return `${hours}h ago`;
  return 'Just now';
}

function mapClient360(snapshot: Client360Snapshot): Client360Data {
  const identity = snapshot.identity ?? {};
  const lead = snapshot.current_lead ?? {};
  const interactions = snapshot.recent_interactions ?? [];
  const last = interactions[0];
  const qdScore = bestQdScore(snapshot);
  const facts: Record<string, string> = {};
  if (lead.budget_band) facts.budget = lead.budget_band;
  if (lead.urgency) facts.timeline = lead.urgency;
  if (identity.buyer_type) facts.buyerType = identity.buyer_type;
  if (identity.persona_labels?.length) facts.persona = identity.persona_labels.join(', ');

  return {
    id: identity.person_id || snapshot.client_ref || '',
    name: identity.full_name || 'Unknown Client',
    location: snapshot.property_interests?.[0]?.project_name || lead.budget_band || undefined,
    primaryPhone: identity.primary_phone || undefined,
    qdScore,
    qdDelta: 0,
    stageName: stageLabel(lead.status),
    stageEmoji: stageEmoji(lead.status),
    lastContactRelative: relativeDate(last?.happened_at),
    lastContactChannel: last?.channel || 'crm',
    aiInsight: snapshot.recommended_next_actions?.[0] || snapshot.active_opportunities?.[0]?.next_action || undefined,
    extractedFacts: facts,
    objections: [...(lead.objections ?? []), ...(snapshot.risk_flags ?? [])],
    qdHistory: Object.entries(snapshot.qd_overview ?? {}).map(([label, item]) => ({
      date: item.computed_at || new Date().toISOString(),
      score: scoreToPercent(item.current_value),
      label: label.replace(/_/g, ' '),
    })),
  };
}

function mapConversationEvents(snapshot: Client360Snapshot): ConversationEvent[] {
  return (snapshot.recent_interactions ?? []).map((event, index) => {
    const type = event.channel === 'email' ? 'email' : event.channel === 'call' || event.channel === 'phone_call' ? 'call' : 'whatsapp';
    return {
      id: event.interaction_id || `${snapshot.client_ref || 'client'}-${index}`,
      type,
      timestamp: event.happened_at || new Date().toISOString(),
      timestampRelative: relativeDate(event.happened_at),
      subject: event.interaction_type || undefined,
      direction: 'outbound',
      duration: undefined,
      hasTranscript: false,
      keyMoments: event.summary ? [event.summary] : [],
      messages: type === 'whatsapp' ? [{ sender: 'client', text: event.summary || 'Interaction recorded in CRM.' }] : undefined,
    };
  });
}

function mapPropertyInterests(snapshot: Client360Snapshot): PropertyInterest[] {
  return (snapshot.property_interests ?? []).map((item, index) => ({
    id: item.interest_id || `${snapshot.client_ref || 'property'}-${index}`,
    projectName: item.project_name || 'Unknown Project',
    unitName: item.unit_preference || 'Preferred Unit',
    config: item.configuration || 'Configuration not captured',
    area: 'Area TBD',
    price: item.budget_min != null && item.budget_max != null ? `₹${item.budget_min}Cr - ₹${item.budget_max}Cr` : 'Budget TBD',
    isPrimary: index === 0 || item.priority === 1,
    engagementLevel: index === 0 ? 'High' : 'Medium',
  }));
}

function mapTasks(snapshot: Client360Snapshot): Task[] {
  return (snapshot.tasks ?? []).map((task, index) => ({
    id: task.reminder_id || `${snapshot.client_ref || 'task'}-${index}`,
    label: task.title || task.notes || 'Follow up with client',
    dueAt: task.due_at || undefined,
    status: task.status === 'done' ? 'done' : task.status === 'snoozed' ? 'snoozed' : 'pending',
    isDueToday: task.due_at ? new Date(task.due_at).toDateString() === new Date().toDateString() : false,
    isAIGenerated: task.created_by_type === 'ai',
  }));
}
