'use client';

import { useEffect, useId, useMemo, useRef, useState } from 'react';
import {
  type ColumnDef,
  type OnChangeFn,
  type PaginationState,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  useReactTable,
} from '@tanstack/react-table';
import { DataTablePagination } from '@/components/data-table/DataTablePagination';
import { useAuth } from '@/components/auth-context';
import { hasAnyDjangoPermission } from '@/lib/permissions';

/**
 * Rejection Analytics — why candidates were rejected, in the recruiter's scope.
 *
 * The table, its columns, wording, colours and the totals strip are exactly as
 * they were inline on the dashboard; what's new is the fixed-height scroll
 * area, the pagination footer and the collapse toggle.
 *
 * RBAC
 * ----
 * The backend only includes `rejection_analytics` in the overview payload when
 * the caller may view the Candidates module (resolved from the menus table —
 * see apps/dashboard/action_points.py), and ships the codes that unlocked it.
 * This component re-applies the same check before rendering, so a stale cached
 * payload can't surface the widget to a role that lost the permission. No role
 * name is hardcoded here.
 */

export interface RejectionReason {
  reason: string;
  count: number;
}

export interface RejectionRecord {
  candidate_id: number;
  candidate_name: string;
  jd_id: number;
  jd_title: string;
  reason: string;
}

export interface RejectionAnalytics {
  total_rejected: number;
  /** Aggregated reason -> count (kept for any other consumer); the card
   * itself now renders the per-candidate `records` list below instead. */
  reasons: RejectionReason[];
  records: RejectionRecord[];
  /** View permission codes for the module this reports on; ANY one unlocks it. */
  permissions?: string[];
}

const PAGE_SIZE_OPTIONS = [5, 10, 20, 50];

/** Fixed body height — the card keeps its footprint whatever the page size. */
const BODY_HEIGHT = 'h-[260px]';

interface RejectionAnalyticsCardProps {
  data: RejectionAnalytics | null | undefined;
  /** JD currently selected in the dashboard filter ('' = all assigned JDs). */
  scopeLabel?: string;
}

export default function RejectionAnalyticsCard({
  data,
  scopeLabel = '',
}: RejectionAnalyticsCardProps) {
  const { user } = useAuth();
  const bodyId = useId();

  const [collapsed, setCollapsed] = useState(false);
  const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 10 });

  const scrollRef = useRef<HTMLDivElement | null>(null);
  // Last known scroll offset, kept live so expanding can restore it.
  const scrollTopRef = useRef(0);

  const records = useMemo(() => data?.records ?? [], [data]);

  // Columns exist so the shared DataTablePagination can drive paging off a real
  // table instance; the rows below keep the widget's original cell markup.
  const columns = useMemo<ColumnDef<RejectionRecord>[]>(
    () => [
      { accessorKey: 'candidate_name', header: 'Candidate' },
      { accessorKey: 'jd_title', header: 'JD' },
      { accessorKey: 'reason', header: 'Reason' },
    ],
    [],
  );

  // The page index is clamped on every render, so a shorter refreshed list can
  // never strand the view on a page that no longer exists — and because the
  // clamped value is what the table reads AND what nav updaters receive, no
  // corrective effect (and no page reset on refresh) is needed.
  const maxPageIndex = Math.max(0, Math.ceil(records.length / pagination.pageSize) - 1);
  const safePagination = useMemo<PaginationState>(
    () => ({
      pageIndex: Math.min(pagination.pageIndex, maxPageIndex),
      pageSize: pagination.pageSize,
    }),
    [pagination.pageIndex, pagination.pageSize, maxPageIndex],
  );

  const handlePaginationChange: OnChangeFn<PaginationState> = (updater) => {
    const next = typeof updater === 'function' ? updater(safePagination) : updater;
    setPagination({ pageSize: next.pageSize, pageIndex: Math.max(0, next.pageIndex) });
  };

  const table = useReactTable({
    data: records,
    columns,
    state: { pagination: safePagination },
    onPaginationChange: handlePaginationChange,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    autoResetPageIndex: false,
  });

  // Restore the scroll offset after expanding — `display:none` drops it while
  // the body is hidden. The body stays mounted, so the page, page size and the
  // dashboard's own filters are untouched and no data is refetched.
  useEffect(() => {
    if (!collapsed && scrollRef.current) {
      scrollRef.current.scrollTop = scrollTopRef.current;
    }
  }, [collapsed]);

  const toggleCollapsed = () => {
    if (!collapsed) {
      scrollTopRef.current = scrollRef.current?.scrollTop ?? scrollTopRef.current;
    }
    setCollapsed((c) => !c);
  };

  // Hidden entirely without the View permission (the backend also withholds it).
  if (!data || !hasAnyDjangoPermission(user, data.permissions)) return null;

  const rows = table.getRowModel().rows;

  return (
    <div>
      <div className="mb-3">
        <h3 className="text-base font-bold text-[#495057] dark:text-white uppercase tracking-wider">Rejection Analytics</h3>
        <p className="text-xs text-vz-muted mt-0.5">
          Who was rejected and why{scopeLabel ? ` for ${scopeLabel}` : ' across your assigned JDs'}.
        </p>
      </div>
      <div className="bg-white dark:bg-slate-900 border border-vz-border dark:border-slate-800 shadow-sm">
        {/* Card header — never scrolls, and is all that remains when collapsed. */}
        <div className="px-4 py-3 border-b border-vz-border dark:border-slate-800 flex items-center justify-between gap-2">
          <span className="text-[11px] uppercase tracking-wider text-vz-muted font-bold">Total Rejected Candidates</span>
          <div className="flex items-center gap-2.5">
            <span className="text-lg font-black text-rose-600 dark:text-rose-400">
              {data.total_rejected}
            </span>
            <button
              type="button"
              onClick={toggleCollapsed}
              aria-expanded={!collapsed}
              aria-controls={bodyId}
              title={collapsed ? 'Expand Rejection Analytics' : 'Collapse Rejection Analytics'}
              className="w-6 h-6 flex items-center justify-center border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 hover:bg-slate-50 dark:hover:bg-slate-800 text-slate-600 dark:text-slate-300 transition cursor-pointer"
            >
              <i className={`fa-solid ${collapsed ? 'fa-chevron-down' : 'fa-chevron-up'} text-[10px]`} />
            </button>
          </div>
        </div>

        {/* Body stays mounted while collapsed (just hidden), so collapsing never
            unmounts the table, refetches, or resets the page. */}
        <div id={bodyId} className={collapsed ? 'hidden' : ''}>
          {records.length === 0 ? (
            <p className="px-4 py-6 text-center text-xs text-vz-muted">
              No rejections recorded{scopeLabel ? ' for this JD' : ''} yet.
            </p>
          ) : (
            <>
              {/* Fixed-height scroll area — only this scrolls. */}
              <div
                ref={scrollRef}
                onScroll={(e) => {
                  scrollTopRef.current = (e.target as HTMLDivElement).scrollTop;
                }}
                className={`${BODY_HEIGHT} overflow-auto custom-scrollbar`}
              >
                <table className="w-full text-xs">
                  {/* Sticky so the column labels stay put while rows scroll,
                      matching the shared DataTable's header behaviour. */}
                  <thead className="sticky top-0 z-10">
                    <tr className="bg-slate-50 dark:bg-slate-950/40 border-b border-vz-border dark:border-slate-800">
                      <th className="text-left py-2.5 px-4 text-[10px] font-extrabold uppercase tracking-wider text-vz-muted">Candidate</th>
                      <th className="text-left py-2.5 px-4 text-[10px] font-extrabold uppercase tracking-wider text-vz-muted">JD</th>
                      <th className="text-left py-2.5 px-4 text-[10px] font-extrabold uppercase tracking-wider text-vz-muted">Reason</th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-slate-100 dark:divide-slate-800">
                    {rows.map((row) => {
                      const r = row.original;
                      return (
                        <tr key={r.candidate_id} className="hover:bg-slate-50/50 dark:hover:bg-slate-900/30 transition">
                          <td className="py-2.5 px-4 font-semibold">
                            {/* Opens the existing Candidates page in a new tab,
                                pinned to exactly this candidate — same
                                `?ids=` drill-down every other card uses, so
                                permissions/filters/pagination are all reused. */}
                            <button
                              type="button"
                              onClick={() =>
                                window.open(
                                  `/candidates?ids=${r.candidate_id}&label=${encodeURIComponent(r.candidate_name)}`,
                                  '_blank',
                                  'noopener,noreferrer',
                                )
                              }
                              className="text-[#405189] dark:text-indigo-400 hover:underline cursor-pointer text-left"
                            >
                              {r.candidate_name}
                            </button>
                          </td>
                          <td className="py-2.5 px-4 text-slate-600 dark:text-slate-300">{r.jd_title}</td>
                          <td className="py-2.5 px-4 text-slate-700 dark:text-slate-300">{r.reason}</td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>

              {/* The project's shared pagination control, unchanged. */}
              <DataTablePagination table={table} pageSizeOptions={PAGE_SIZE_OPTIONS} />
            </>
          )}
        </div>
      </div>
    </div>
  );
}
