'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { motion } from 'framer-motion';
import Cookies from 'js-cookie';
import { toast } from 'react-toastify';
import { api } from '@/lib/api';
import OverallDashboardFilters from './OverallDashboardFilters';
import OverallDashboardSummaryCards from './OverallDashboardSummaryCards';
import OverallConversionFunnel from './OverallConversionFunnel';
import OverallRecruiterPerformanceTable from './OverallRecruiterPerformanceTable';
import OverallJobPerformanceTable from './OverallJobPerformanceTable';
import TopPerformingJobsWidget from './TopPerformingJobsWidget';
import type {
  FunnelData,
  JobPerformanceRow,
  OverallFiltersState,
  OverallSummary,
  RecruiterPerformanceRow,
  TopJobsData,
} from './types';
import { EMPTY_OVERALL_FILTERS } from './types';

const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000/api/v1';
const BASE = '/reports/overall-dashboard';

function toQuery(filters: OverallFiltersState): string {
  const params = new URLSearchParams();
  Object.entries(filters).forEach(([k, v]) => { if (v) params.set(k, v); });
  const qs = params.toString();
  return qs ? `?${qs}` : '';
}

function Section({ title, subtitle, icon, children, collapsible = false }: {
  title: string;
  subtitle: string;
  icon: string;
  children: React.ReactNode;
  collapsible?: boolean;
}) {
  const [open, setOpen] = useState(true);
  return (
    <motion.section
      initial={{ opacity: 0, y: 16 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.35 }}
      className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none p-5 shadow-sm"
    >
      <div
        className={`flex items-center gap-3 ${open ? 'mb-4' : ''} ${collapsible ? 'cursor-pointer select-none' : ''}`}
        onClick={collapsible ? () => setOpen((o) => !o) : undefined}
      >
        <div className="w-9 h-9 rounded-none bg-indigo-50 dark:bg-indigo-950/50 flex items-center justify-center">
          <i className={`${icon} text-indigo-600 dark:text-indigo-400 text-sm`} />
        </div>
        <div className="flex-1 min-w-0">
          <h2 className="text-sm font-bold text-slate-800 dark:text-white">{title}</h2>
          <p className="text-xs text-slate-400 dark:text-slate-500">{subtitle}</p>
        </div>
        {collapsible && (
          <button
            type="button"
            onClick={(e) => { e.stopPropagation(); setOpen((o) => !o); }}
            className="w-8 h-8 shrink-0 flex items-center justify-center rounded-none border border-slate-200 dark:border-slate-800 text-slate-500 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-slate-800 transition cursor-pointer"
            title={open ? 'Collapse' : 'Expand'}
            aria-label={open ? 'Collapse section' : 'Expand section'}
          >
            <i className={`fa-solid fa-chevron-${open ? 'up' : 'down'} text-xs`} />
          </button>
        )}
      </div>
      {(!collapsible || open) && children}
    </motion.section>
  );
}

function SkeletonBlock({ className }: { className: string }) {
  return <div className={`bg-slate-100 dark:bg-slate-800 rounded-none animate-pulse ${className}`} />;
}

function LoadingSkeleton() {
  return (
    <div className="space-y-5">
      <div className="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-4">
        {[...Array(8)].map((_, i) => <SkeletonBlock key={i} className="h-36" />)}
      </div>
      <SkeletonBlock className="h-64" />
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
        <SkeletonBlock className="h-72" />
        <SkeletonBlock className="h-72" />
      </div>
      <SkeletonBlock className="h-80" />
      <SkeletonBlock className="h-80" />
    </div>
  );
}

const EXPORT_OPTIONS = [
  { format: 'csv', label: 'CSV', icon: 'fa-solid fa-file-csv' },
  { format: 'excel', label: 'Excel', icon: 'fa-solid fa-file-excel' },
  { format: 'pdf', label: 'PDF', icon: 'fa-solid fa-file-pdf' },
] as const;

export default function OverallDashboard() {
  const [filters, setFilters] = useState<OverallFiltersState>({ ...EMPTY_OVERALL_FILTERS });
  const [summary, setSummary] = useState<OverallSummary | null>(null);
  const [funnel, setFunnel] = useState<FunnelData | null>(null);
  const [recruiters, setRecruiters] = useState<RecruiterPerformanceRow[]>([]);
  const [jobs, setJobs] = useState<JobPerformanceRow[]>([]);
  const [topJobs, setTopJobs] = useState<TopJobsData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [exporting, setExporting] = useState<string | null>(null);
  const [exportSection, setExportSection] = useState<'job-performance' | 'recruiter-performance'>('job-performance');

  // Monotonic token so a slow, older request set can never overwrite the data
  // of a newer filter selection (each filter change fires 5 parallel calls).
  const loadSeqRef = useRef(0);

  const load = useCallback(() => {
    const seq = ++loadSeqRef.current;
    const qs = toQuery(filters);
    setLoading(true);
    setError(null);
    Promise.all([
      api.get(`${BASE}/summary/${qs}`),
      api.get(`${BASE}/conversion-funnel/${qs}`),
      api.get(`${BASE}/recruiter-performance/${qs}`),
      api.get(`${BASE}/job-performance/${qs}`),
      api.get(`${BASE}/top-performing-jobs/${qs}`),
    ])
      .then(([s, fn, rp, jp, tp]) => {
        if (seq !== loadSeqRef.current) return;   // stale response — a newer filter load superseded this one
        setSummary((s as { data: OverallSummary }).data);
        setFunnel((fn as { data: FunnelData }).data);
        setRecruiters((rp as { data: { recruiters: RecruiterPerformanceRow[] } }).data.recruiters);
        setJobs((jp as { data: { jobs: JobPerformanceRow[] } }).data.jobs);
        setTopJobs((tp as { data: TopJobsData }).data);
      })
      .catch((e: unknown) => {
        if (seq !== loadSeqRef.current) return;
        const msg = e instanceof Error ? e.message : 'Failed to load dashboard data';
        setError(msg);
        toast.error(msg);
      })
      .finally(() => {
        if (seq === loadSeqRef.current) setLoading(false);
      });
  }, [filters]);

  useEffect(load, [load]);

  const handleExport = async (format: string) => {
    setExporting(format);
    try {
      const params = new URLSearchParams();
      Object.entries(filters).forEach(([k, v]) => { if (v) params.set(k, v); });
      params.set('format', format);
      params.set('section', exportSection);

      const res = await fetch(`${API_BASE_URL}${BASE}/export/?${params.toString()}`, {
        headers: { Authorization: `Bearer ${Cookies.get('access_token')}` },
      });
      if (!res.ok) throw new Error(`Export failed (status ${res.status})`);

      const disposition = res.headers.get('content-disposition') || '';
      const filename = disposition.match(/filename="?([^";]+)"?/)?.[1]
        || `${exportSection.replace(/-/g, '_')}.${format === 'excel' ? 'xlsx' : format}`;

      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      a.click();
      URL.revokeObjectURL(url);
      toast.success(`${format.toUpperCase()} report downloaded`);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : 'Export failed');
    } finally {
      setExporting(null);
    }
  };

  return (
    <div className="space-y-5">
      {/* Title row + export actions */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
        <div>
          <h1 className="text-xl font-bold text-slate-900 dark:text-white">Overall ATS Dashboard</h1>
          <p className="text-sm text-slate-500 dark:text-slate-400 mt-0.5">
            Real-time recruitment analytics and hiring performance across all active jobs.
          </p>
        </div>
        <div className="flex items-center gap-2 flex-wrap">
          <select
            value={exportSection}
            onChange={(e) => setExportSection(e.target.value as typeof exportSection)}
            className="px-2.5 py-2 rounded-none text-xs font-semibold bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 text-slate-700 dark:text-slate-300 focus:outline-none focus:border-indigo-500 transition"
            title="Which table to export"
          >
            <option value="job-performance">Job Performance</option>
            <option value="recruiter-performance">Recruiter Performance</option>
          </select>
          {EXPORT_OPTIONS.map(({ format, label, icon }) => (
            <button
              key={format}
              onClick={() => handleExport(format)}
              disabled={exporting !== null || loading}
              className="flex items-center gap-2 px-3.5 py-2 rounded-none text-xs font-semibold bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 text-slate-700 dark:text-slate-300 hover:border-indigo-500/60 hover:text-indigo-600 dark:hover:text-indigo-400 transition disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
              title={`Export ${exportSection.replace('-', ' ')} as ${label}`}
            >
              <i className={`${exporting === format ? 'fa-solid fa-spinner fa-spin' : icon} text-sm`} />
              {label}
            </button>
          ))}
        </div>
      </div>

      {/* Filters */}
      <OverallDashboardFilters filters={filters} onChange={setFilters} />

      {loading ? (
        <LoadingSkeleton />
      ) : error ? (
        <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none p-10 text-center shadow-sm">
          <i className="fa-solid fa-triangle-exclamation text-3xl text-amber-500 mb-3" />
          <p className="text-sm font-semibold text-slate-700 dark:text-slate-300">Could not load dashboard data</p>
          <p className="text-xs text-slate-400 dark:text-slate-500 mt-1">{error}</p>
          <button
            onClick={load}
            className="mt-4 bg-[#405189] hover:bg-[#364574] text-white px-4 py-2 rounded-none text-sm font-medium transition cursor-pointer"
          >
            <i className="fa-solid fa-rotate-right mr-2" />
            Retry
          </button>
        </div>
      ) : (
        <>
          {summary && <OverallDashboardSummaryCards summary={summary} />}

          <div className="grid grid-cols-1 lg:grid-cols-2 gap-5 items-start">
            {funnel && (
              <Section
                title="Recruitment Conversion Funnel"
                subtitle="Stage-to-stage conversion and drop-off"
                icon="fa-solid fa-filter"
                collapsible
              >
                <OverallConversionFunnel data={funnel} />
              </Section>
            )}

            {topJobs && (
              <Section
                title="Top Performing Jobs"
                subtitle="Top 5 by candidates, hires and conversion"
                icon="fa-solid fa-trophy"
                collapsible
              >
                <TopPerformingJobsWidget data={topJobs} />
              </Section>
            )}
          </div>

          <Section
            title="Recruiter Performance"
            subtitle="Hiring output per recruiter on active JDs — highest hires first"
            icon="fa-solid fa-user-tie"
          >
            <OverallRecruiterPerformanceTable rows={recruiters} />
          </Section>

          <Section
            title="Job Performance"
            subtitle="Pipeline health of every active job description"
            icon="fa-solid fa-briefcase"
          >
            <OverallJobPerformanceTable rows={jobs} />
          </Section>
        </>
      )}
    </div>
  );
}
