import { useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Columns3, Table } from 'lucide-react';
import { cn } from '../lib/cn';
import { Badge, Card, KpiCard, LeadRow, LEAD_GRID, Pagination } from '../components';
import type { Kpi, Lead, SegmentDatum } from '../types';
import { useLeads } from '../api/leads';
import { STAGES } from '../api/config';
import { AddLeadButton } from '../components/activities';
import { LeadFilters } from '../components/LeadFilters';
import { recordToLead } from '../api/adapters';
import { applyFilters, EMPTY_FILTER, type FilterState } from '../api/filters';

const PAGE_SIZE = 10;

// Funnel milestones (subset of STAGES) — count = leads that have *reached* it.
const FUNNEL_STEPS: Array<{ label: string; stage: string }> = [
  { label: 'New Lead', stage: 'New Lead' },
  { label: 'Qualified', stage: 'Qualified' },
  { label: 'Assigned', stage: 'Assigned' },
  { label: 'Contacted', stage: 'Contacted' },
  { label: 'Meeting', stage: 'Meeting Scheduled' },
  { label: 'Recommended', stage: 'Product Recommended' },
  { label: 'Underwriting', stage: 'Underwriting' },
  { label: 'Issued', stage: 'Policy Issued' },
];

const SEGMENT_COLORS: Record<string, string> = {
  Hot: 'var(--sunrise-500)',
  Warm: 'var(--amber-500)',
  Cold: 'var(--slate-400)',
};

function buildKpis(leads: Lead[]): Kpi[] {
  const total = leads.length || 1;
  const hot = leads.filter((l) => l.segment === 'Hot').length;
  const issuedIdx = STAGES.indexOf('Policy Issued');
  const issued = leads.filter((l) => l.stage >= issuedIdx && l.stage >= 0).length;
  const aiHandled = leads.filter((l) => l.ownerAi).length;
  return [
    { label: 'Total leads', value: String(leads.length) },
    { label: 'Hot leads', value: String(Math.round((hot / total) * 100)), unit: '%' },
    { label: 'Conversion rate', value: String(Math.round((issued / total) * 100)), unit: '%' },
    { label: 'AI-handled', value: String(Math.round((aiHandled / total) * 100)), unit: '%', accent: true },
  ];
}

function buildFunnel(leads: Lead[]) {
  const total = leads.length || 1;
  return FUNNEL_STEPS.map((step) => {
    const idx = STAGES.indexOf(step.stage as (typeof STAGES)[number]);
    const count = leads.filter((l) => l.stage >= idx).length;
    return { stage: step.label, count, pct: Math.round((count / total) * 100) };
  });
}

function buildSegments(leads: Lead[]): SegmentDatum[] {
  return (['Hot', 'Warm', 'Cold'] as const).map((label) => ({
    label,
    count: leads.filter((l) => l.segment === label).length,
    color: SEGMENT_COLORS[label],
  }));
}

function FunnelChart({ data }: { data: ReturnType<typeof buildFunnel> }) {
  return (
    <div className="flex flex-col gap-2.5">
      {data.map((f) => (
        <div key={f.stage} className="flex items-center gap-3">
          <span className="w-24 shrink-0 text-xs font-medium text-muted text-right">{f.stage}</span>
          <div className="flex-1 h-[26px] bg-slate-100 rounded-sm overflow-hidden">
            <div
              className="h-full bg-sunrise rounded-sm flex items-center justify-end pr-2.5 transition-[width] duration-700"
              style={{ width: `${Math.max(f.pct, 6)}%` }}
            >
              <span className="text-2xs font-bold text-white nums">{f.count.toLocaleString('en-IN')}</span>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

function SegmentDonut({ segments }: { segments: SegmentDatum[] }) {
  const total = segments.reduce((a, b) => a + b.count, 0) || 1;
  let acc = 0;
  const stops = segments
    .map((s) => {
      const start = (acc / total) * 360;
      acc += s.count;
      const end = (acc / total) * 360;
      return `${s.color} ${start}deg ${end}deg`;
    })
    .join(',');

  return (
    <div className="flex items-center gap-5">
      <div className="w-[120px] h-[120px] rounded-full relative shrink-0" style={{ background: `conic-gradient(${stops})` }}>
        <div className="absolute inset-3.5 rounded-full bg-card flex flex-col items-center justify-center">
          <span className="font-numeric font-extrabold text-2xl text-strong leading-none">
            {segments.reduce((a, b) => a + b.count, 0).toLocaleString('en-IN')}
          </span>
          <span className="text-[10px] text-faint font-semibold">active</span>
        </div>
      </div>
      <div className="flex flex-col gap-2.5 flex-1">
        {segments.map((s) => (
          <div key={s.label} className="flex items-center gap-2.5">
            <span className="w-2.5 h-2.5 rounded-[3px] shrink-0" style={{ background: s.color }} />
            <span className="text-sm font-semibold text-body flex-1">{s.label}</span>
            <span className="font-numeric font-bold text-md text-strong nums">{s.count.toLocaleString('en-IN')}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// Minimal card — monochrome text with a single segment dot as the only accent
// (segment already encodes hot/warm/cold, so the score stays neutral).
function KanbanCard({ lead, onClick }: { lead: Lead; onClick: () => void }) {
  return (
    <div
      onClick={onClick}
      className="bg-card border border-border-subtle rounded-md shadow-xs p-3 cursor-pointer flex flex-col gap-1.5 transition-all duration-150 hover:shadow-md hover:-translate-y-px"
    >
      <div className="flex items-start justify-between gap-2">
        <div className="min-w-0">
          <div className="text-sm font-semibold text-strong truncate">{lead.name}</div>
          <div className="text-2xs text-faint truncate">
            {[lead.city, lead.channel].filter(Boolean).join(' · ')}
          </div>
        </div>
        <span className="font-numeric font-bold text-sm text-muted nums shrink-0">{lead.score}</span>
      </div>
      <div className="flex items-center gap-1.5 text-2xs text-faint min-w-0">
        <span
          className="w-1.5 h-1.5 rounded-full shrink-0"
          style={{ background: SEGMENT_COLORS[lead.segment] ?? 'var(--slate-400)' }}
          title={lead.segment}
        />
        <span className="truncate">{lead.lastAction}</span>
      </div>
    </div>
  );
}

function KanbanBoard({ leads, onOpenLead }: { leads: Lead[]; onOpenLead: (l: Lead) => void }) {
  const cols = STAGES.slice(0, 8);
  return (
    <div className="flex gap-3.5 overflow-x-auto pb-1.5 scrollbar-slim">
      {cols.map((stage, idx) => {
        const items = leads.filter((l) => l.stage === idx);
        return (
          <div key={stage} className="shrink-0 w-[236px] flex flex-col gap-2.5">
            <div className="flex items-center justify-between px-1 py-0.5">
              <span className="text-xs font-bold text-strong">{stage}</span>
              <span className="text-2xs font-bold text-faint bg-slate-100 rounded-pill min-w-5 text-center px-[7px] py-0.5 nums">
                {items.length}
              </span>
            </div>
            {/* Card list caps at viewport height and scrolls per-column so a
                busy stage doesn't blow up the whole board's height. */}
            <div className="flex flex-col gap-2.5 bg-slate-100 rounded-md p-2.5 min-h-[120px] max-h-[70vh] overflow-y-auto scrollbar-slim">
              {items.length ? (
                items.map((l) => <KanbanCard key={l.id} lead={l} onClick={() => onOpenLead(l)} />)
              ) : (
                <div className="text-2xs text-faint text-center py-4">No leads</div>
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
}

function ViewToggle({ view, onChange }: { view: string; onChange: (v: string) => void }) {
  const opts: Array<[string, string, typeof Table]> = [
    ['table', 'Table', Table],
    ['kanban', 'Kanban', Columns3],
  ];
  return (
    <div className="flex gap-0.5 bg-slate-100 rounded-md p-[3px]">
      {opts.map(([id, label, Icon]) => (
        <button
          key={id}
          onClick={() => onChange(id)}
          className={cn(
            'inline-flex items-center gap-1.5 border-none cursor-pointer font-sans text-xs font-semibold px-3 py-1.5 rounded-sm transition-all duration-150',
            view === id ? 'bg-card text-strong shadow-xs' : 'bg-transparent text-muted',
          )}
        >
          <Icon size={14} />
          {label}
        </button>
      ))}
    </div>
  );
}

export function PipelineScreen() {
  const [view, setView] = useState('table');
  const navigate = useNavigate();
  const openLead = (l: Lead) => navigate(`/leads/${l.id}`);

  const { leads, records, fields, loading, error, refetch } = useLeads();
  const [filters, setFilters] = useState<FilterState>(EMPTY_FILTER);

  // KPIs / funnel / segments summarize the whole pipeline; the list below is
  // what the filter narrows.
  const kpis = useMemo(() => buildKpis(leads), [leads]);
  const funnel = useMemo(() => buildFunnel(leads), [leads]);
  const segments = useMemo(() => buildSegments(leads), [leads]);
  const visibleLeads = useMemo(
    () => applyFilters(records, filters, fields).map(recordToLead),
    [records, filters, fields],
  );

  // Table-view pagination (the kanban board shows every stage at once). Page is
  // clamped in <Pagination> and reset when the filter set changes.
  const [page, setPage] = useState(1);
  useEffect(() => setPage(1), [filters]);
  const start = (Math.min(page, Math.max(1, Math.ceil(visibleLeads.length / PAGE_SIZE))) - 1) * PAGE_SIZE;
  const pageLeads = visibleLeads.slice(start, start + PAGE_SIZE);

  return (
    <div className="flex flex-col gap-5 max-w-[1240px] mx-auto">
      {error && (
        <div className="text-sm text-amber-700 bg-escalated-soft border border-amber-300 rounded-md px-4 py-3">
          Couldn’t load leads: {error}
        </div>
      )}

      {/* KPI row */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
        {kpis.map((k, i) => (
          <KpiCard key={i} {...k} />
        ))}
      </div>

      {/* charts — cards stay equal height (aligned bottoms); the shorter
          segments content is vertically centered so there's no dead space. */}
      <div className="grid grid-cols-1 lg:grid-cols-[1.7fr_1fr] gap-4">
        <Card title="Pipeline funnel" action={<Badge tone="neutral">Live</Badge>}>
          <FunnelChart data={funnel} />
        </Card>
        <Card title="Lead segments" className="flex flex-col" bodyClassName="flex-1 flex items-center">
          <SegmentDonut segments={segments} />
        </Card>
      </div>

      {/* leads — table or kanban */}
      <Card
        title="Leads"
        pad={false}
        action={
          <div className="flex gap-2.5 items-center">
            <ViewToggle view={view} onChange={setView} />
            <AddLeadButton onDone={refetch} />
          </div>
        }
      >
        <LeadFilters records={records} fields={fields} value={filters} onChange={setFilters} />
        {loading ? (
          <div className="p-10 text-center text-sm text-faint">Loading leads…</div>
        ) : view === 'table' ? (
          <div className="overflow-x-auto">
            <div className="min-w-[760px]">
              <div
                className={cn(
                  'grid gap-3 px-[18px] py-[11px] bg-slate-50 border-b border-border-subtle text-[10px] font-bold uppercase tracking-[0.06em] text-faint',
                  LEAD_GRID,
                )}
              >
                <span>Lead</span>
                <span>Score</span>
                <span>Segment</span>
                <span>Channel</span>
                <span>Owner</span>
                <span>Last action</span>
              </div>
              {pageLeads.length ? (
                pageLeads.map((l) => <LeadRow key={l.id} lead={l} onClick={() => openLead(l)} />)
              ) : (
                <div className="p-10 text-center text-sm text-faint">No leads match these filters.</div>
              )}
            </div>
          </div>
        ) : (
          <div className="p-5">
            <KanbanBoard leads={visibleLeads} onOpenLead={openLead} />
          </div>
        )}
        {view === 'table' && !loading && (
          <Pagination page={page} pageSize={PAGE_SIZE} total={visibleLeads.length} onPage={setPage} />
        )}
      </Card>
    </div>
  );
}
