import {
  For, Show, createResource, createSignal, onCleanup, onMount,
} from 'solid-js';
import { A } from '@solidjs/router';
import AdminShell from '~/components/AdminShell';
import {
  Users, Building2, TrendingUp, CreditCard, Clock, BadgeCheck,
  BriefcaseBusiness, HeadphonesIcon, Download, Plus, X, GripVertical,
} from 'lucide-solid';
import {
  DragDropProvider, DragDropSensors, SortableProvider,
  createSortable, closestCenter, type DragEventHandler,
} from '@thisbeyond/solid-dnd';

// ── Types ─────────────────────────────────────────────────────────────────────

type StatWidget = {
  id: string;
  label: string;
  icon: any;
  apiPath: string;
  totalKey: string[];
  prefix?: string;
  deltaLabel: string;
  deltaValue: string;
  deltaUp: boolean;
  href: string;
};

type ChartWidget = {
  id: string;
  label: string;
  subtitle: string;
  type: 'line' | 'bar';
};

// ── Stat widget definitions ───────────────────────────────────────────────────

const STAT_DEFS: StatWidget[] = [
  {
    id: 'total-users',
    label: 'Total Users',
    icon: Users,
    apiPath: '/api/gateway/api/admin/users?limit=1',
    totalKey: ['total', 'count'],
    deltaLabel: 'from last month',
    deltaValue: '+12.5%',
    deltaUp: true,
    href: '/admin/users',
  },
  {
    id: 'active-companies',
    label: 'Active Companies',
    icon: Building2,
    apiPath: '/api/gateway/api/admin/companies?limit=1',
    totalKey: ['total', 'count'],
    deltaLabel: 'from last month',
    deltaValue: '+8.2%',
    deltaUp: true,
    href: '/admin/company',
  },
  {
    id: 'open-leads',
    label: 'Open Leads',
    icon: TrendingUp,
    apiPath: '/api/gateway/api/admin/leads?status=open&limit=1',
    totalKey: ['total', 'count'],
    deltaLabel: 'from last month',
    deltaValue: '-3.1%',
    deltaUp: false,
    href: '/admin/leads',
  },
  {
    id: 'credits-purchased',
    label: 'Credits Purchased',
    icon: CreditCard,
    apiPath: '/api/gateway/api/admin/credits?limit=1',
    totalKey: ['total', 'count'],
    prefix: '₹',
    deltaLabel: 'from last month',
    deltaValue: '+18.7%',
    deltaUp: true,
    href: '/admin/credit',
  },
  {
    id: 'pending-approvals',
    label: 'Pending Approvals',
    icon: Clock,
    apiPath: '/api/gateway/api/admin/approvals?status=pending&limit=1',
    totalKey: ['total', 'count'],
    deltaLabel: 'action required',
    deltaValue: 'Today',
    deltaUp: false,
    href: '/admin/approval',
  },
  {
    id: 'pending-verifications',
    label: 'Pending Verifications',
    icon: BadgeCheck,
    apiPath: '/api/gateway/api/admin/verifications?status=pending&limit=1',
    totalKey: ['total', 'count'],
    deltaLabel: 'in queue',
    deltaValue: 'Today',
    deltaUp: false,
    href: '/admin/verification-status',
  },
  {
    id: 'jobs-posted',
    label: 'Jobs Posted',
    icon: BriefcaseBusiness,
    apiPath: '/api/gateway/api/admin/jobs?limit=1',
    totalKey: ['total', 'count'],
    deltaLabel: 'from last month',
    deltaValue: '+5.4%',
    deltaUp: true,
    href: '/admin/jobs',
  },
  {
    id: 'support-tickets',
    label: 'Support Tickets',
    icon: HeadphonesIcon,
    apiPath: '/api/gateway/api/admin/support?status=open&limit=1',
    totalKey: ['total', 'count'],
    deltaLabel: 'open tickets',
    deltaValue: 'Active',
    deltaUp: false,
    href: '/admin/support',
  },
];

const CHART_DEFS: ChartWidget[] = [
  { id: 'leads-trend',      label: 'Leads Trend',      subtitle: 'Monthly leads performance overview',           type: 'line' },
  { id: 'revenue-overview', label: 'Revenue Overview',  subtitle: 'Monthly revenue vs expenses comparison',       type: 'bar'  },
  { id: 'user-growth',      label: 'User Growth',       subtitle: 'Monthly new user registrations',               type: 'line' },
];

// Default layout
const DEFAULT_STATS  = ['total-users', 'active-companies', 'open-leads', 'credits-purchased'];
const DEFAULT_CHARTS = ['leads-trend', 'revenue-overview'];
const STORAGE_KEY    = 'nxtgauge_admin_dash_v1';

function loadLayout(): { stats: string[]; charts: string[] } {
  if (typeof localStorage === 'undefined') return { stats: DEFAULT_STATS, charts: DEFAULT_CHARTS };
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (raw) return JSON.parse(raw);
  } catch { /* */ }
  return { stats: DEFAULT_STATS, charts: DEFAULT_CHARTS };
}

function saveLayout(stats: string[], charts: string[]) {
  if (typeof localStorage === 'undefined') return;
  localStorage.setItem(STORAGE_KEY, JSON.stringify({ stats, charts }));
}

// ── ApexCharts wrapper ────────────────────────────────────────────────────────

function Chart(props: { id: string; type: 'line' | 'bar'; height?: number }) {
  let el!: HTMLDivElement;
  let chartInstance: any = null;

  // onCleanup must be registered synchronously (outside async) to stay in reactive scope
  onCleanup(() => { chartInstance?.destroy(); chartInstance = null; });

  onMount(async () => {
    const { default: ApexCharts } = await import('apexcharts');
    if (!el) return;

    const isLine = props.type === 'line';
    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];

    const options: Record<string, any> = {
      chart: {
        type: props.type,
        height: props.height ?? 240,
        toolbar: { show: false },
        fontFamily: 'Exo 2, sans-serif',
        animations: { enabled: true, speed: 400 },
      },
      grid: {
        borderColor: '#f1f5f9',
        strokeDashArray: 4,
        xaxis: { lines: { show: false } },
        yaxis: { lines: { show: true } },
      },
      xaxis: {
        categories: months,
        axisBorder: { show: false },
        axisTicks: { show: false },
        labels: { style: { colors: '#94a3b8', fontSize: '12px' } },
      },
      tooltip: { theme: 'light', style: { fontFamily: 'Exo 2, sans-serif' } },
      legend: { show: false },
      ...(isLine
        ? {
            series: [{ name: 'Leads', data: [65, 59, 80, 81, 90, 115] }],
            stroke: { curve: 'smooth', width: 2.5, colors: ['#fd6216'] },
            fill: {
              type: 'gradient',
              gradient: {
                shadeIntensity: 1,
                opacityFrom: 0.35,
                opacityTo: 0.02,
                colorStops: [
                  { offset: 0, color: '#fd6216', opacity: 0.35 },
                  { offset: 100, color: '#fd6216', opacity: 0 },
                ],
              },
            },
            markers: { size: 0 },
            colors: ['#fd6216'],
            yaxis: { labels: { style: { colors: '#94a3b8', fontSize: '12px' } }, min: 0, max: 130, tickAmount: 4 },
          }
        : {
            series: [{ name: 'Revenue (₹)', data: [35000, 41000, 38000, 52000, 61000, 67000] }],
            plotOptions: { bar: { borderRadius: 4, columnWidth: '50%' } },
            fill: { colors: ['#0a1d37'] },
            colors: ['#0a1d37'],
            dataLabels: { enabled: false },
            yaxis: {
              labels: {
                style: { colors: '#94a3b8', fontSize: '12px' },
                formatter: (v: number) => `${(v / 1000).toFixed(0)}k`,
              },
            },
          }),
    };

    chartInstance = new ApexCharts(el, options);
    await chartInstance.render();
  });

  return <div ref={el!} />;
}

// ── Stat count fetcher ────────────────────────────────────────────────────────

async function fetchCount(path: string, keys: string[]): Promise<string> {
  try {
    const res = await fetch(path);
    if (!res.ok) return '—';
    const data = await res.json();
    for (const k of keys) {
      if (data[k] !== undefined) return String(Number(data[k]).toLocaleString('en-IN'));
    }
    return '—';
  } catch {
    return '—';
  }
}

// ── Sortable stat card ────────────────────────────────────────────────────────

function SortableStatCard(props: {
  def: StatWidget;
  onRemove: () => void;
  editMode: boolean;
}) {
  const sortable = createSortable(props.def.id);
  const [count] = createResource(() => fetchCount(props.def.apiPath, props.def.totalKey));
  const Icon = props.def.icon;

  return (
    <div
      // @ts-ignore
      use:sortable
      class={`relative rounded-2xl border border-gray-200 bg-white p-5 shadow-sm transition-shadow hover:shadow-md ${
        sortable.isActiveDraggable ? 'opacity-50 shadow-lg ring-2 ring-orange-300' : ''
      }`}
    >
      {/* Drag handle */}
      <Show when={props.editMode}>
        <div class="absolute left-2 top-1/2 -translate-y-1/2 cursor-grab text-gray-300 active:cursor-grabbing">
          <GripVertical size={16} />
        </div>
        <button
          type="button"
          onClick={props.onRemove}
          class="absolute -right-2 -top-2 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 text-white shadow-md hover:bg-red-600"
        >
          <X size={10} />
        </button>
      </Show>

      {/* Top row: icon + delta badge */}
      <div class="flex items-start justify-between">
        <div class="flex h-12 w-12 items-center justify-center rounded-2xl bg-orange-50">
          <Icon size={22} class="text-orange-500" />
        </div>
        <span
          class={`flex items-center gap-1 rounded-full px-2.5 py-1 text-[12px] font-bold ${
            props.def.deltaUp
              ? 'bg-green-50 text-green-600'
              : props.def.deltaValue === 'Today' || props.def.deltaValue === 'Active'
              ? 'bg-blue-50 text-blue-600'
              : 'bg-red-50 text-red-500'
          }`}
        >
          <span>{props.def.deltaUp ? '↑' : props.def.deltaValue === 'Today' || props.def.deltaValue === 'Active' ? '' : '↓'}</span>
          {props.def.deltaValue}
        </span>
      </div>

      {/* Label */}
      <p class="mt-4 text-[13px] font-medium text-gray-500">{props.def.label}</p>

      {/* Value */}
      <p class="mt-1 text-3xl font-black tracking-tight text-gray-900">
        <Show when={!count.loading} fallback={<span class="text-xl text-gray-300">Loading…</span>}>
          {props.def.prefix ?? ''}{count()}
        </Show>
      </p>

      {/* Delta label */}
      <p class="mt-1 text-[12px] text-gray-400">{props.def.deltaLabel}</p>

      {/* Link overlay */}
      <Show when={!props.editMode}>
        <A href={props.def.href} class="absolute inset-0 rounded-2xl" aria-label={props.def.label} />
      </Show>
    </div>
  );
}

// ── Sortable chart card ───────────────────────────────────────────────────────

function SortableChartCard(props: {
  def: ChartWidget;
  onRemove: () => void;
  editMode: boolean;
}) {
  const sortable = createSortable(props.def.id);

  return (
    <div
      // @ts-ignore
      use:sortable
      class={`relative rounded-2xl border border-gray-200 bg-white p-5 shadow-sm ${
        sortable.isActiveDraggable ? 'opacity-50 shadow-lg ring-2 ring-orange-300' : ''
      }`}
    >
      <Show when={props.editMode}>
        <div class="absolute left-2 top-1/2 -translate-y-1/2 cursor-grab text-gray-300 active:cursor-grabbing">
          <GripVertical size={16} />
        </div>
        <button
          type="button"
          onClick={props.onRemove}
          class="absolute -right-2 -top-2 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 text-white shadow-md hover:bg-red-600"
        >
          <X size={10} />
        </button>
      </Show>

      <div class="mb-4">
        <h3 class="text-[15px] font-bold text-gray-900">{props.def.label}</h3>
        <p class="mt-0.5 text-[12px] text-gray-400">{props.def.subtitle}</p>
      </div>

      <Chart id={props.def.id} type={props.def.type} height={220} />
    </div>
  );
}

// ── Add Widget Panel ──────────────────────────────────────────────────────────

function AddWidgetPanel(props: {
  activeStats: string[];
  activeCharts: string[];
  onAddStat: (id: string) => void;
  onAddChart: (id: string) => void;
  onClose: () => void;
}) {
  const availableStats  = () => STAT_DEFS.filter((d) => !props.activeStats.includes(d.id));
  const availableCharts = () => CHART_DEFS.filter((d) => !props.activeCharts.includes(d.id));

  return (
    <div class="rounded-2xl border border-dashed border-orange-300 bg-orange-50/40 p-5">
      <div class="mb-4 flex items-center justify-between">
        <h3 class="text-[14px] font-bold text-gray-800">Add Widgets</h3>
        <button
          type="button"
          onClick={props.onClose}
          class="text-gray-400 hover:text-gray-600"
        >
          <X size={16} />
        </button>
      </div>

      <Show when={availableStats().length > 0}>
        <p class="mb-2 text-[11px] font-bold uppercase tracking-widest text-gray-400">Stat Cards</p>
        <div class="mb-4 flex flex-wrap gap-2">
          <For each={availableStats()}>
            {(def) => {
              const Icon = def.icon;
              return (
                <button
                  type="button"
                  onClick={() => props.onAddStat(def.id)}
                  class="flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-3 py-2 text-[13px] font-medium text-gray-700 shadow-sm transition-all hover:border-orange-300 hover:bg-orange-50 hover:text-orange-600"
                >
                  <Icon size={14} class="text-orange-400" />
                  {def.label}
                  <Plus size={12} class="text-gray-400" />
                </button>
              );
            }}
          </For>
        </div>
      </Show>

      <Show when={availableCharts().length > 0}>
        <p class="mb-2 text-[11px] font-bold uppercase tracking-widest text-gray-400">Charts</p>
        <div class="flex flex-wrap gap-2">
          <For each={availableCharts()}>
            {(def) => (
              <button
                type="button"
                onClick={() => props.onAddChart(def.id)}
                class="flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-3 py-2 text-[13px] font-medium text-gray-700 shadow-sm transition-all hover:border-orange-300 hover:bg-orange-50 hover:text-orange-600"
              >
                {def.label}
                <Plus size={12} class="text-gray-400" />
              </button>
            )}
          </For>
        </div>
      </Show>

      <Show when={availableStats().length === 0 && availableCharts().length === 0}>
        <p class="text-[13px] text-gray-400">All widgets are already on your dashboard.</p>
      </Show>
    </div>
  );
}

// ── Dashboard page ────────────────────────────────────────────────────────────

export default function AdminDashboard() {
  const layout = loadLayout();
  const [statIds, setStatIds]   = createSignal<string[]>(layout.stats);
  const [chartIds, setChartIds] = createSignal<string[]>(layout.charts);
  const [editMode, setEditMode] = createSignal(false);
  const [showAdd, setShowAdd]   = createSignal(false);

  // Persist whenever layout changes
  const persist = () => saveLayout(statIds(), chartIds());

  const statDefs  = () => statIds().map((id) => STAT_DEFS.find((d) => d.id === id)!).filter(Boolean);
  const chartDefs = () => chartIds().map((id) => CHART_DEFS.find((d) => d.id === id)!).filter(Boolean);

  // ── Stat drag ──────────────────────────────────────────────────────────────
  const onStatDragEnd: DragEventHandler = ({ draggable, droppable }) => {
    if (!droppable || draggable.id === droppable.id) return;
    const ids = [...statIds()];
    const from = ids.indexOf(String(draggable.id));
    const to   = ids.indexOf(String(droppable.id));
    if (from < 0 || to < 0) return;
    ids.splice(to, 0, ...ids.splice(from, 1));
    setStatIds(ids);
    persist();
  };

  // ── Chart drag ─────────────────────────────────────────────────────────────
  const onChartDragEnd: DragEventHandler = ({ draggable, droppable }) => {
    if (!droppable || draggable.id === droppable.id) return;
    const ids = [...chartIds()];
    const from = ids.indexOf(String(draggable.id));
    const to   = ids.indexOf(String(droppable.id));
    if (from < 0 || to < 0) return;
    ids.splice(to, 0, ...ids.splice(from, 1));
    setChartIds(ids);
    persist();
  };

  const removeStatWidget  = (id: string) => { setStatIds((p) => p.filter((x) => x !== id));  persist(); };
  const removeChartWidget = (id: string) => { setChartIds((p) => p.filter((x) => x !== id)); persist(); };
  const addStatWidget     = (id: string) => { setStatIds((p) => [...p, id]);  persist(); setShowAdd(false); };
  const addChartWidget    = (id: string) => { setChartIds((p) => [...p, id]); persist(); setShowAdd(false); };

  const handleExport = () => window.print();

  return (
    <AdminShell>
      <div class="space-y-6">

        {/* ── Page header ── */}
        <div class="flex items-start justify-between gap-4">
          <div>
            <h1 class="text-2xl font-black text-gray-900">Dashboard Overview</h1>
            <p class="mt-1 text-[13px] text-gray-500">
              Welcome back! Here's what's happening with your platform today.
            </p>
          </div>
          <div class="flex shrink-0 items-center gap-2">
            <button
              type="button"
              onClick={() => { setEditMode((v) => !v); setShowAdd(false); }}
              class={`flex items-center gap-2 rounded-xl border px-4 py-2.5 text-[13px] font-semibold transition-all ${
                editMode()
                  ? 'border-orange-300 bg-orange-50 text-orange-600'
                  : 'border-gray-200 bg-white text-gray-700 hover:border-gray-300 hover:bg-gray-50'
              }`}
            >
              {editMode() ? 'Done' : 'Customise'}
            </button>
            <Show when={editMode()}>
              <button
                type="button"
                onClick={() => setShowAdd((v) => !v)}
                class="flex items-center gap-2 rounded-xl border border-dashed border-orange-400 bg-orange-50 px-4 py-2.5 text-[13px] font-semibold text-orange-600 hover:bg-orange-100"
              >
                <Plus size={15} />
                Add Widget
              </button>
            </Show>
            <button
              type="button"
              onClick={handleExport}
              class="flex items-center gap-2 rounded-xl bg-gray-900 px-4 py-2.5 text-[13px] font-semibold text-white transition-colors hover:bg-gray-800"
            >
              <Download size={15} />
              Export Report
            </button>
          </div>
        </div>

        {/* ── Add widget panel ── */}
        <Show when={showAdd()}>
          <AddWidgetPanel
            activeStats={statIds()}
            activeCharts={chartIds()}
            onAddStat={addStatWidget}
            onAddChart={addChartWidget}
            onClose={() => setShowAdd(false)}
          />
        </Show>

        {/* ── Stat cards ── */}
        <Show when={statDefs().length > 0}>
          <DragDropProvider onDragEnd={onStatDragEnd} collisionDetector={closestCenter}>
            <DragDropSensors />
            <SortableProvider ids={statIds()}>
              <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
                <For each={statDefs()}>
                  {(def) => (
                    <SortableStatCard
                      def={def}
                      editMode={editMode()}
                      onRemove={() => removeStatWidget(def.id)}
                    />
                  )}
                </For>
              </div>
            </SortableProvider>
          </DragDropProvider>
        </Show>

        {/* ── Charts ── */}
        <Show when={chartDefs().length > 0}>
          <DragDropProvider onDragEnd={onChartDragEnd} collisionDetector={closestCenter}>
            <DragDropSensors />
            <SortableProvider ids={chartIds()}>
              <div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
                <For each={chartDefs()}>
                  {(def) => (
                    <SortableChartCard
                      def={def}
                      editMode={editMode()}
                      onRemove={() => removeChartWidget(def.id)}
                    />
                  )}
                </For>
              </div>
            </SortableProvider>
          </DragDropProvider>
        </Show>

        {/* Empty state */}
        <Show when={statDefs().length === 0 && chartDefs().length === 0}>
          <div class="flex flex-col items-center justify-center rounded-2xl border border-dashed border-gray-300 py-20 text-center">
            <p class="text-[15px] font-semibold text-gray-500">Your dashboard is empty.</p>
            <p class="mt-1 text-[13px] text-gray-400">Click "Customise" then "Add Widget" to get started.</p>
          </div>
        </Show>

      </div>
    </AdminShell>
  );
}
