import { useEffect, useMemo, useState } from 'react';
import {
  Activity,
  AlertTriangle,
  ArrowRight,
  Check,
  Clock,
  Database,
  Mail,
  Phone,
  Search,
  Sparkles,
  UserRound,
  Zap,
} from 'lucide-react';
import { Input } from '@/components/ui/input';
import {
  fetchOracleClientData,
  fetchOracleClientDataDetail,
  patchOracleClientData,
} from '@/lib/crmApi';
import type { OracleClientDataDetail, OracleClientDataListItem } from '@/types/crmTypes';

const STAGES = [
  'new',
  'contacted',
  'qualified',
  'site_visit_scheduled',
  'site_visited',
  'negotiation',
  'booking_initiated',
  'booked',
];

function fmt(value: unknown): string {
  if (value == null || value === '') return '-';
  if (typeof value === 'number') return Number.isInteger(value) ? String(value) : value.toFixed(2);
  return String(value);
}

function shortDate(value: unknown): string {
  if (!value) return '-';
  const date = new Date(String(value));
  if (Number.isNaN(date.getTime())) return String(value);
  return date.toLocaleString();
}

function FieldRow({ label, value }: { label: string; value: unknown }) {
  return (
    <div className="grid grid-cols-[150px_1fr] gap-3 border-b border-white/[0.06] py-2.5 text-sm">
      <span className="text-zinc-500">{label}</span>
      <span className="min-w-0 break-words text-zinc-200">{fmt(value)}</span>
    </div>
  );
}

function EmptyDiagnostic({ error, loading }: { error: string | null; loading: boolean }) {
  return (
    <div className="flex h-full min-h-[420px] items-center justify-center p-8">
      <div className="max-w-xl rounded-3xl border border-amber-400/20 bg-amber-500/[0.08] p-6">
        <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-2xl border border-amber-300/25 bg-amber-400/10">
          {loading ? <Database className="h-5 w-5 animate-pulse text-amber-200" /> : <AlertTriangle className="h-5 w-5 text-amber-200" />}
        </div>
        <p className="text-xs font-semibold uppercase tracking-[0.24em] text-amber-200">Client data unavailable</p>
        <h3 className="mt-2 text-xl font-semibold text-zinc-50">
          {loading ? 'Loading Velocity CRM data...' : 'The CRM lens has no rows to show.'}
        </h3>
        <p className="mt-3 text-sm leading-6 text-zinc-400">
          {error
            ? error
            : 'The local frontend is alive, but the CRM API returned no clients. Start the local backend, start Docker/Postgres, apply the canonical schema, and seed synthetic_crm_v2 before verifying this tab.'}
        </p>
        <div className="mt-5 rounded-2xl border border-white/10 bg-black/25 p-4 text-xs leading-6 text-zinc-400">
          <p className="font-semibold text-zinc-200">Expected local stack</p>
          <p>Backend: http://127.0.0.1:8001</p>
          <p>DB: 127.0.0.1:54329 / velocity_local</p>
          <p>Dataset: db assets/synthetic_crm_v2/csv</p>
        </div>
      </div>
    </div>
  );
}

export function ClientDataLens() {
  const [query, setQuery] = useState('');
  const [items, setItems] = useState<OracleClientDataListItem[]>([]);
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [detail, setDetail] = useState<OracleClientDataDetail | null>(null);
  const [loadingList, setLoadingList] = useState(false);
  const [loadingDetail, setLoadingDetail] = useState(false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [draft, setDraft] = useState({
    full_name: '',
    primary_email: '',
    primary_phone: '',
    buyer_type: '',
    communication_preference: '',
    best_contact_time: '',
    budget_band: '',
    urgency: '',
  });

  useEffect(() => {
    const handle = window.setTimeout(() => {
      setLoadingList(true);
      setError(null);
      void fetchOracleClientData({ search: query, limit: 80 })
        .then(({ items: rows }) => {
          setItems(rows);
          setSelectedId((current) => current ?? rows[0]?.person_id ?? null);
          if (!rows.length) {
            setDetail(null);
          }
        })
        .catch((err) => {
          setItems([]);
          setSelectedId(null);
          setDetail(null);
          setError(err instanceof Error ? err.message : 'Failed to reach the CRM client data API.');
        })
        .finally(() => setLoadingList(false));
    }, 180);
    return () => window.clearTimeout(handle);
  }, [query]);

  useEffect(() => {
    if (!selectedId) return;
    setLoadingDetail(true);
    setError(null);
    void fetchOracleClientDataDetail(selectedId)
      .then((data) => {
        const profile = data.profile ?? {};
        setDetail(data);
        setDraft({
          full_name: String(profile.full_name ?? ''),
          primary_email: String(profile.primary_email ?? ''),
          primary_phone: String(profile.primary_phone ?? ''),
          buyer_type: String(profile.buyer_type ?? ''),
          communication_preference: String(profile.communication_preference ?? ''),
          best_contact_time: String(profile.best_contact_time ?? ''),
          budget_band: String(profile.budget_band ?? ''),
          urgency: String(profile.urgency ?? ''),
        });
      })
      .catch((err) => {
        setDetail(null);
        setError(err instanceof Error ? err.message : 'Failed to load the selected client record.');
      })
      .finally(() => setLoadingDetail(false));
  }, [selectedId]);

  const selected = useMemo(
    () => items.find((item) => item.person_id === selectedId) ?? items[0] ?? null,
    [items, selectedId],
  );
  const profile = detail?.profile ?? {};
  const currentStage = String(profile.lead_status ?? selected?.lead_status ?? 'new');
  const qdScore = Number(selected?.qd_score ?? 0);
  const activeStageIndex = Math.max(0, STAGES.indexOf(currentStage));

  async function saveDraft() {
    if (!selectedId) return;
    setSaving(true);
    setError(null);
    try {
      await patchOracleClientData(selectedId, draft);
      const fresh = await fetchOracleClientDataDetail(selectedId);
      setDetail(fresh);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to save client data.');
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="relative z-10 grid h-full min-h-0 grid-cols-[360px_minmax(0,1fr)] gap-4 overflow-hidden px-5 pb-5 pt-3">
      <aside className="flex min-h-0 flex-col overflow-hidden rounded-3xl border border-cyan-400/15 bg-[linear-gradient(180deg,rgba(8,47,73,0.16),rgba(0,0,0,0.22))]">
        <div className="border-b border-white/10 p-5">
          <div className="mb-4 flex items-start justify-between">
            <div>
              <p className="text-xs font-semibold uppercase tracking-[0.28em] text-cyan-300">Client Data</p>
              <h2 className="mt-1 text-xl font-semibold text-zinc-50">Velocity CRM Lens</h2>
              <p className="mt-1 text-xs text-zinc-500">Search, inspect, edit, and follow the client signal trail.</p>
            </div>
            <Sparkles className="h-5 w-5 text-cyan-200" />
          </div>
          <div className="relative">
            <Search className="absolute left-3 top-2.5 h-4 w-4 text-zinc-500" />
            <Input
              value={query}
              onChange={(event) => setQuery(event.target.value)}
              placeholder="Search name, phone, email, project..."
              className="h-10 border-white/10 bg-black/25 pl-9 text-sm text-zinc-100"
            />
          </div>
        </div>

        <div className="min-h-0 flex-1 overflow-y-auto p-2">
          {items.map((item) => (
            <button
              key={item.person_id}
              type="button"
              onClick={() => setSelectedId(item.person_id)}
              className={`mb-2 w-full rounded-2xl border p-3 text-left transition ${
                item.person_id === selectedId
                  ? 'border-cyan-300/40 bg-cyan-500/12 shadow-[0_0_24px_rgba(34,211,238,0.08)]'
                  : 'border-white/8 bg-white/[0.03] hover:bg-white/[0.06]'
              }`}
            >
              <div className="flex items-start gap-3">
                <div className="flex h-10 w-10 items-center justify-center rounded-2xl border border-blue-400/20 bg-blue-500/15 text-sm font-semibold text-blue-100">
                  {item.full_name.slice(0, 1)}
                </div>
                <div className="min-w-0 flex-1">
                  <p className="truncate text-sm font-semibold text-zinc-100">{item.full_name}</p>
                  <p className="truncate text-xs text-zinc-500">{item.projects || item.buyer_type || 'No project interest'}</p>
                  <div className="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-zinc-400">
                    <span className="rounded-full bg-cyan-500/10 px-2 py-0.5 text-cyan-300">QD {Math.round((item.qd_score || 0) * 100)}</span>
                    <span>{item.days_since_contact == null ? 'No contact clock' : `${item.days_since_contact}d since contact`}</span>
                  </div>
                </div>
              </div>
            </button>
          ))}
          {!items.length && (
            <div className="px-4 py-7 text-sm text-zinc-500">
              {loadingList ? 'Loading clients...' : 'No clients found.'}
            </div>
          )}
        </div>
      </aside>

      <main className="min-w-0 overflow-hidden rounded-3xl border border-white/10 bg-black/20">
        {!selected ? (
          <EmptyDiagnostic error={error} loading={loadingList} />
        ) : (
          <div className="flex h-full min-h-0 flex-col">
            <section className="border-b border-white/10 bg-[linear-gradient(135deg,rgba(14,116,144,0.14),rgba(15,23,42,0.35))] p-5">
              {error && (
                <div className="mb-4 rounded-2xl border border-amber-400/20 bg-amber-500/10 px-4 py-3 text-sm text-amber-100">
                  {error}
                </div>
              )}
              <div className="flex flex-wrap items-start justify-between gap-4">
                <div>
                  <p className="text-xs uppercase tracking-[0.24em] text-zinc-500">Contact Record</p>
                  <h1 className="mt-1 text-3xl font-semibold text-zinc-50">{selected.full_name}</h1>
                  <div className="mt-3 flex flex-wrap gap-4 text-sm text-zinc-400">
                    <span className="flex items-center gap-1.5"><Phone className="h-4 w-4" />{fmt(selected.primary_phone)}</span>
                    <span className="flex items-center gap-1.5"><Mail className="h-4 w-4" />{fmt(selected.primary_email)}</span>
                    <span className="flex items-center gap-1.5"><UserRound className="h-4 w-4" />{fmt(selected.broker_name)}</span>
                  </div>
                </div>
                <div className="grid grid-cols-3 gap-3">
                  <div className="rounded-2xl border border-cyan-400/20 bg-cyan-500/10 px-4 py-3 text-right">
                    <p className="text-xs text-cyan-300">QD Signal</p>
                    <p className="text-3xl font-semibold text-cyan-100">{Math.round(qdScore * 100)}</p>
                  </div>
                  <div className="rounded-2xl border border-white/10 bg-black/25 px-4 py-3">
                    <p className="text-xs text-zinc-500">Last Contact</p>
                    <p className="mt-1 max-w-[160px] truncate text-sm font-semibold text-zinc-100">{shortDate(selected.last_contact_at)}</p>
                  </div>
                  <div className="rounded-2xl border border-white/10 bg-black/25 px-4 py-3">
                    <p className="text-xs text-zinc-500">Next Action</p>
                    <p className="mt-1 max-w-[180px] truncate text-sm font-semibold text-zinc-100">{fmt(selected.next_best_action)}</p>
                  </div>
                </div>
              </div>

              <div className="mt-5 grid grid-cols-8 overflow-hidden rounded-full border border-white/10 bg-white/[0.04]">
                {STAGES.map((stage, index) => {
                  const active = activeStageIndex >= index;
                  return (
                    <div key={stage} className={`py-2 text-center text-[11px] font-semibold ${active ? 'bg-blue-500/70 text-white' : 'text-zinc-500'}`}>
                      {stage.replace(/_/g, ' ')}
                    </div>
                  );
                })}
              </div>
            </section>

            <section className="min-h-0 flex-1 overflow-y-auto p-5">
              {loadingDetail && <p className="mb-4 text-sm text-zinc-500">Loading record...</p>}
              <div className="grid gap-5 xl:grid-cols-[minmax(0,1fr)_410px]">
                <div className="space-y-5">
                  <div className="rounded-3xl border border-white/10 bg-white/[0.03] p-5">
                    <div className="mb-4 flex items-center justify-between">
                      <div>
                        <h3 className="text-base font-semibold text-zinc-100">Editable Details</h3>
                        <p className="text-xs text-zinc-500">Typed API writes only. Oracle SQL remains read-only.</p>
                      </div>
                      <button
                        type="button"
                        onClick={() => void saveDraft()}
                        disabled={saving}
                        className="rounded-xl bg-blue-500 px-4 py-2 text-xs font-semibold text-white disabled:opacity-50"
                      >
                        <Check className="mr-1 inline h-3.5 w-3.5" />
                        {saving ? 'Saving...' : 'Save changes'}
                      </button>
                    </div>
                    <div className="grid gap-3 md:grid-cols-2">
                      {Object.entries(draft).map(([key, value]) => (
                        <label key={key} className="text-xs text-zinc-500">
                          {key.replace(/_/g, ' ')}
                          <Input
                            value={value}
                            onChange={(event) => setDraft((current) => ({ ...current, [key]: event.target.value }))}
                            className="mt-1 h-9 border-white/10 bg-black/25 text-sm text-zinc-100"
                          />
                        </label>
                      ))}
                    </div>
                  </div>

                  <div className="rounded-3xl border border-white/10 bg-white/[0.03] p-5">
                    <h3 className="mb-4 text-base font-semibold text-zinc-100">Property Interests</h3>
                    <div className="grid gap-3 md:grid-cols-2">
                      {(detail?.property_interests ?? []).slice(0, 8).map((interest, index) => (
                        <div key={String(interest.interest_id ?? index)} className="rounded-2xl border border-white/10 bg-black/25 p-4">
                          <p className="font-medium text-zinc-100">{fmt(interest.project_name)}</p>
                          <p className="mt-1 text-xs text-zinc-500">{fmt(interest.configuration)} | {fmt(interest.budget_min)}-{fmt(interest.budget_max)}</p>
                          <p className="mt-2 text-xs text-cyan-300">Priority {fmt(interest.priority)}</p>
                        </div>
                      ))}
                      {!(detail?.property_interests ?? []).length && <p className="text-sm text-zinc-500">No property interests loaded for this client.</p>}
                    </div>
                  </div>

                  <div className="rounded-3xl border border-white/10 bg-white/[0.03] p-5">
                    <h3 className="mb-4 text-base font-semibold text-zinc-100">Unified Engagement Timeline</h3>
                    <div className="space-y-3">
                      {(detail?.timeline ?? []).slice(0, 24).map((event) => (
                        <div key={event.id} className="flex gap-3 rounded-2xl border border-white/8 bg-black/25 p-3">
                          <Activity className="mt-1 h-4 w-4 text-blue-300" />
                          <div className="min-w-0 flex-1">
                            <p className="text-sm font-medium text-zinc-100">{fmt(event.title || event.type)}</p>
                            <p className="mt-1 text-xs text-zinc-500">{fmt(event.summary)}</p>
                          </div>
                          <span className="whitespace-nowrap text-[11px] text-zinc-600">{shortDate(event.date)}</span>
                        </div>
                      ))}
                      {!(detail?.timeline ?? []).length && <p className="text-sm text-zinc-500">No timeline events loaded. Seed v2 interactions/messages/calls/visits to populate this rail.</p>}
                    </div>
                  </div>
                </div>

                <aside className="space-y-5">
                  <div className="rounded-3xl border border-blue-400/20 bg-blue-500/10 p-5">
                    <p className="text-xs uppercase tracking-[0.24em] text-blue-300">Next Best Action</p>
                    <p className="mt-2 text-lg font-semibold text-zinc-100">{fmt(selected.next_best_action ?? profile.recommended_action)}</p>
                    <p className="mt-3 text-sm leading-6 text-zinc-400">{fmt(profile.rationale)}</p>
                  </div>
                  <div className="rounded-3xl border border-white/10 bg-white/[0.03] p-5">
                    <h3 className="mb-3 flex items-center gap-2 text-base font-semibold text-zinc-100"><Clock className="h-4 w-4" /> Engagement Intelligence</h3>
                    <FieldRow label="Last Contact" value={shortDate(selected.last_contact_at)} />
                    <FieldRow label="Channel" value={selected.last_channel} />
                    <FieldRow label="Days Since" value={selected.days_since_contact} />
                    <FieldRow label="Preference" value={selected.communication_preference} />
                    <FieldRow label="Best Time" value={profile.best_contact_time} />
                  </div>
                  <div className="rounded-3xl border border-white/10 bg-white/[0.03] p-5">
                    <h3 className="mb-3 flex items-center gap-2 text-base font-semibold text-zinc-100"><Zap className="h-4 w-4 text-cyan-300" /> Extracted Facts</h3>
                    {(detail?.extracted_facts ?? []).slice(0, 10).map((fact, index) => (
                      <div key={String(fact.fact_id ?? index)} className="mb-2 rounded-2xl bg-black/25 p-3 text-xs">
                        <p className="font-semibold text-cyan-200">{fmt(fact.fact_type)}</p>
                        <p className="mt-1 text-zinc-400">{fmt(fact.fact_value)}</p>
                      </div>
                    ))}
                    {!(detail?.extracted_facts ?? []).length && <p className="text-sm text-zinc-500">No extracted facts loaded.</p>}
                  </div>
                  <div className="rounded-3xl border border-white/10 bg-white/[0.03] p-5">
                    <h3 className="mb-3 text-base font-semibold text-zinc-100">Open Opportunities</h3>
                    {(detail?.opportunities ?? []).slice(0, 8).map((opp, index) => (
                      <div key={String(opp.opportunity_id ?? index)} className="mb-2 flex items-center justify-between rounded-2xl bg-black/25 p-3 text-xs">
                        <span className="text-zinc-200">{fmt(opp.project_name ?? opp.stage)}</span>
                        <ArrowRight className="h-3.5 w-3.5 text-zinc-500" />
                      </div>
                    ))}
                    {!(detail?.opportunities ?? []).length && <p className="text-sm text-zinc-500">No opportunities loaded.</p>}
                  </div>
                </aside>
              </div>
            </section>
          </div>
        )}
      </main>
    </div>
  );
}
