'use client';

import { useEffect, useRef, useState } from 'react';
import type { PaginationState, RowSelectionState } from '@tanstack/react-table';
import { useRouter } from 'next/navigation';

function MapPin({ className }: { className?: string }) {
  return <i className={`fa-solid fa-location-dot ${className}`}></i>;
}

function Users({ className }: { className?: string }) {
  return <i className={`fa-solid fa-users ${className}`}></i>;
}

function Mail({ className }: { className?: string }) {
  return <i className={`fa-solid fa-envelope ${className}`}></i>;
}

function Phone({ className }: { className?: string }) {
  return <i className={`fa-solid fa-phone ${className}`}></i>;
}

function X({ className }: { className?: string }) {
  return <i className={`fa-solid fa-xmark ${className}`}></i>;
}

import { api } from '@/lib/api';
import PhoneInput from '@/components/PhoneInput';
import { useAuth } from '@/components/auth-context';
import LocationAsyncSelect from '@/components/LocationAsyncSelect';
import { showConfirmDelete, showSuccess, showError, showImportSummary } from '@/lib/confirm';
import { isSourceEmpty, sourceLabel, SOURCE_EMPTY } from '@/lib/sources';
import { DataTable } from '@/components/data-table/DataTable';
import { DataTableActions } from '@/components/data-table/DataTableActions';
import SearchableSelect from '@/components/SearchableSelect';
import SendSmsMailModal from '@/components/SendSmsMailModal';
import NotifyCandidateModal from '@/components/NotifyCandidateModal';
import { SKILL_OPTIONS } from '@/data/skills';
import { toast } from 'react-toastify';
import BackToDashboard from '@/components/BackToDashboard';
import { ResumePreviewModal } from '@/components/ResumePreviewModal';
import { BulkUploadPreviewModal } from '@/components/BulkUploadPreviewModal';
import { DeletedCandidatesModal } from '@/components/DeletedCandidatesModal';
import { formatDate, formatDateTime } from '@/lib/dates';

const CURRENT_YEAR = new Date().getFullYear();
const YEAR_OPTIONS = Array.from({ length: CURRENT_YEAR + 5 - 1950 + 1 }, (_, i) => {
  const year = String(CURRENT_YEAR + 5 - i);
  return { value: year, label: year };
});

const LANGUAGE_OPTIONS = [
  { value: 'English', label: 'English' },
  { value: 'Hindi', label: 'Hindi' },
  { value: 'Spanish', label: 'Spanish' },
  { value: 'German', label: 'German' },
];

const EXP_YEAR_OPTIONS = Array.from({ length: 51 }, (_, i) => ({ value: String(i), label: String(i) }));
const EXP_MONTH_OPTIONS = Array.from({ length: 12 }, (_, i) => ({ value: String(i), label: String(i) }));

// Card-view filter option lists
const FILTER_EXP_YEARS = Array.from({ length: 50 }, (_, i) => ({ value: String(i + 1), label: `${i + 1} ${i === 0 ? 'Year' : 'Years'}` }));
const FILTER_EXP_MONTHS = Array.from({ length: 12 }, (_, i) => ({ value: String(i), label: `${i} ${i === 1 ? 'Month' : 'Months'}` }));
const SALARY_0_TO_100_OPTIONS = Array.from({ length: 101 }, (_, i) => ({ value: String(i), label: String(i) }));

const LAKHS_OPTIONS = Array.from({ length: 101 }, (_, i) => ({
  value: String(i),
  label: `${i} ${i === 1 ? 'Lakh' : 'Lakhs'}`,
}));

const THOUSANDS_OPTIONS = Array.from({ length: 100 }, (_, i) => ({
  value: String(i),
  label: `${String(i).padStart(2, '0')} ${i === 1 ? 'Thousand' : 'Thousands'}`,
}));

function parseCtcParts(val: string | number | null | undefined) {
  if (val === null || val === undefined || val === '') return { lakhs: '', thousands: '0' };
  const num = Number(val);
  if (isNaN(num)) return { lakhs: '', thousands: '0' };
  const lakhs = Math.floor(num);
  const thousands = Math.round((num - lakhs) * 100);
  return { lakhs: String(lakhs), thousands: String(thousands) };
}

function combineCtcParts(lakhsStr: string, thousandsStr: string) {
  if (lakhsStr === '' && (!thousandsStr || thousandsStr === '0')) return '';
  const lakhs = Number(lakhsStr || '0');
  const thousands = Number(thousandsStr || '0');
  const total = lakhs + (thousands / 100);
  return total.toFixed(2);
}

function sanitizeDecimal(val: string): string {
  const sanitized = val.replace(/[^0-9.]/g, '');
  const parts = sanitized.split('.');
  if (parts.length > 2) {
    return parts[0] + '.' + parts.slice(1).join('');
  }
  return sanitized;
}

interface CandidateListItem {
  id: number;
  full_name: string;
  first_name: string;
  last_name: string;
  email: string;
  phone_number: string;
  fresher: boolean;
  total_experience: string | null;
  date_of_birth?: string | null;
  gender?: string | null;
  employment_type?: string | null;
  current_ctc?: string | number | null;
  preferred_location?: string | null;
  current_company: string | null;
  current_role: string | null;
  city: string | null;
  state: string | null;
  skills: string[];
  status: string;
  source?: string;
  resume: string | null;
  resume_url?: string | null;
  created_at: string;
  updated_at: string;
}

export default function CandidatesPage() {
  const router = useRouter();
  const { user } = useAuth();
  const [candidates, setCandidates] = useState<CandidateListItem[]>([]);
  const [resumeView, setResumeView] = useState<{ url: string; name: string } | null>(null);
  const [draftModalOpen, setDraftModalOpen] = useState(false);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState('');
  // Dashboard drill-down: exact candidate ids from `?ids=` (null = no drill-down).
  // Seeded synchronously from the URL so the first render is already scoped to
  // exactly the records behind the dashboard card's count.
  const [focusIds, setFocusIds] = useState<number[] | null>(() => {
    if (typeof window === 'undefined') return null;
    const raw = new URLSearchParams(window.location.search).get('ids');
    if (raw === null) return null;
    return raw.split(',').map((x) => Number(x.trim())).filter((n) => Number.isFinite(n));
  });
  const [focusLabel, setFocusLabel] = useState<string>(() => {
    if (typeof window === 'undefined') return '';
    return new URLSearchParams(window.location.search).get('label') || '';
  });
  // Dashboard drill-down: `?focus=1` (e.g. the Recruiter dashboard's "Rejected
  // Candidates" card) opens this page in a distraction-free mode — just the
  // title + the filtered list, with the Bulk Candidate/Bulk Notification/
  // Inactive Candidates/Add Candidate toolbar hidden, so clicking in to see a
  // specific list doesn't pull the user into unrelated bulk workflows. Every
  // filter, the search box, sorting, pagination, per-row actions, and "View
  // All Records" all keep working exactly as normal — only that one toolbar
  // row is gated on it.
  const [focusMode, setFocusMode] = useState<boolean>(() => {
    if (typeof window === 'undefined') return false;
    return new URLSearchParams(window.location.search).get('focus') === '1';
  });
  // Dashboard drill-down: `?pm_metric=` (e.g. a PM dashboard card — Submitted /
  // Shortlisted / Offered / Joined / Offered Rejected / Rejected) is resolved
  // server-side, fresh on every fetch, using the exact classification the
  // card's count uses (apps.pipeline.pm_metrics) — so the count and the rows
  // shown here can never disagree.
  const [pmMetric, setPmMetric] = useState<string>(() => {
    if (typeof window === 'undefined') return '';
    return new URLSearchParams(window.location.search).get('pm_metric') || '';
  });
  // Dashboard drill-down: `?stage_codes=` (e.g. Admin/Recruiter dashboard
  // cards — "Offered", "Rejected") — an exact-current-stage match, as opposed
  // to `pm_metric`'s "reached or beyond" classification. Same backend
  // function (candidate_ids_for_stage_codes) the card's own count uses.
  const [stageCodes, setStageCodes] = useState<string>(() => {
    if (typeof window === 'undefined') return '';
    return new URLSearchParams(window.location.search).get('stage_codes') || '';
  });
  // Dashboard drill-down: `?owner=me` / `?assigned=me` narrow `pm_metric`/
  // `stage_codes` to JDs created by / assigned to the current user (PM vs.
  // Recruiter dashboards). Org-wide (TA dashboard) sends neither.
  const [ownerMe, setOwnerMe] = useState<boolean>(() => {
    if (typeof window === 'undefined') return false;
    return new URLSearchParams(window.location.search).get('owner') === 'me';
  });
  const [assignedMe, setAssignedMe] = useState<boolean>(() => {
    if (typeof window === 'undefined') return false;
    return new URLSearchParams(window.location.search).get('assigned') === 'me';
  });
  // Dashboard drill-down: `?period=` (TA dashboard's period selector) narrows
  // `pm_metric` to applications created within that calendar-aligned window —
  // same window the card's own count uses.
  const [pmPeriod, setPmPeriod] = useState<string>(() => {
    if (typeof window === 'undefined') return '';
    return new URLSearchParams(window.location.search).get('period') || '';
  });
  // True while any dashboard-card drill-down is active — drives the banner
  // and its "View All Records" reset below.
  const hasDrillDown = !!(focusIds || pmMetric || stageCodes || ownerMe || assignedMe);
  const clearDrillDown = () => {
    setFocusIds(null); setFocusLabel(''); setPmMetric(''); setStageCodes('');
    setOwnerMe(false); setAssignedMe(false); setPmPeriod('');
    // "View All Records" is a full exit back to the normal Candidates page —
    // the distraction-free toolbar (?focus=1) goes away too, so Bulk
    // Candidate/Bulk Notification/Inactive Candidates/Add Candidate reappear
    // and work as usual.
    setFocusMode(false);
    router.replace('/candidates');
  };
  const [statusFilter, setStatusFilter] = useState('ALL');
  const [experienceFilter, setExperienceFilter] = useState('ALL');
  const [sourceFilter, setSourceFilter] = useState('ALL');
  // Job filter — matches candidates assigned to a job by id (#123) or title text.
  const [jobFilter, setJobFilter] = useState('');
  // Table view: State (single, from State master) → City (multi, from City master)
  const [stateFilterId, setStateFilterId] = useState('');
  const [cityFilters, setCityFilters] = useState<string[]>([]);
  const [filterStateOptions, setFilterStateOptions] = useState<{ value: string; label: string }[]>([]);
  const [filterStatesLoading, setFilterStatesLoading] = useState(false);
  const [filterCityOptions, setFilterCityOptions] = useState<{ value: string; label: string }[]>([]);
  const [filterCitiesLoading, setFilterCitiesLoading] = useState(false);
  const [createdFrom, setCreatedFrom] = useState('');
  const [createdTo, setCreatedTo] = useState('');
  // Card view: enhanced filters
  const [expYearsFilter, setExpYearsFilter] = useState('');
  const [expMonthsFilter, setExpMonthsFilter] = useState('');
  const [locationFilters, setLocationFilters] = useState<string[]>([]);
  const [locationSearch, setLocationSearch] = useState('');
  const [companyFilters, setCompanyFilters] = useState<string[]>([]);
  const [skillFilters, setSkillFilters] = useState<string[]>([]);
  const [salaryFrom, setSalaryFrom] = useState('');
  const [salaryTo, setSalaryTo] = useState('');
  const [designationFilters, setDesignationFilters] = useState<string[]>([]);
  const [genderFilter, setGenderFilter] = useState('ALL');
  // Card view: dynamic filter data (loaded once, when the card view is first opened)
  const [cardMastersLoaded, setCardMastersLoaded] = useState(false);
  const [jdLocations, setJdLocations] = useState<{ name: string; count: number }[]>([]);
  const [jdLocationsLoading, setJdLocationsLoading] = useState(false);
  const [clientOptions, setClientOptions] = useState<{ value: string; label: string }[]>([]);
  const [clientsLoading, setClientsLoading] = useState(false);
  const [masterSkillOptions, setMasterSkillOptions] = useState<{ value: string; label: string }[]>([]);
  const [masterSkillsLoading, setMasterSkillsLoading] = useState(false);
  const [filterOpen, setFilterOpen] = useState(false);
  const [viewMode, setViewMode] = useState<'table' | 'cards'>('table');
  const [revealedPhoneId, setRevealedPhoneId] = useState<number | null>(null);
  const [revealedPhone, setRevealedPhone] = useState<string>('');
  const [revealing, setRevealing] = useState(false);
  // Fetch the REAL phone (list value is masked) via the audit-logged endpoint.
  const revealPhone = async (cd: any) => {
    if (revealedPhoneId === cd.id) { setRevealedPhoneId(null); return; }  // toggle off
    setRevealing(true);
    try {
      const r = (await api.get(`/candidates/${cd.id}/reveal-contact/`)) as any;
      setRevealedPhone(r?.data?.phone_number || 'No phone on profile');
      setRevealedPhoneId(cd.id);
    } catch {
      toast.error('Could not reveal phone number.');
    } finally {
      setRevealing(false);
    }
  };
  // Card view: sort / page-size / pagination / selection
  const [cardSort, setCardSort] = useState<'newest' | 'name' | 'experience'>('newest');
  // Unified server-side pagination for BOTH the table and card views. The list
  // never downloads more than one page; all filtering/sorting is server-side
  // (see CandidateListCreateAPIView + apply_candidate_list_filters).
  const [pagination, setPagination] = useState<PaginationState>({ pageIndex: 0, pageSize: 10 });
  // Table-view row selection (checkboxes) for export.
  const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
  const [total, setTotal] = useState(0);
  const [selectedCardIds, setSelectedCardIds] = useState<number[]>([]);
  // Bulk mail (selected cards)
  const [bulkMailOpen, setBulkMailOpen] = useState(false);
  const [bulkMailSubject, setBulkMailSubject] = useState('');
  const [bulkMailBody, setBulkMailBody] = useState('');
  const [bulkMailSending, setBulkMailSending] = useState(false);

  // Bulk Notify — opens the full NotifyCandidateModal (templates, channels, CC,
  // history) pre-loaded with the candidates selected in EITHER view.
  const [bulkNotifyList, setBulkNotifyList] = useState<any[] | null>(null);

  // Candidate objects selected in the current view (table rows OR card checkboxes).
  const getSelectedCandidateObjects = (): any[] => {
    const ids = viewMode === 'table'
      ? Object.keys(rowSelection).filter((k) => rowSelection[k]).map((k) => Number(k))
      : selectedCardIds;
    const byId = new Map(candidates.map((c: any) => [c.id, c]));
    return ids.map((id) => byId.get(id)).filter(Boolean);
  };

  const openBulkNotify = () => {
    const list = getSelectedCandidateObjects();
    if (list.length === 0) { toast.info('Select at least one candidate first.'); return; }
    setBulkNotifyList(list);
  };

  const sendBulkMailToSelected = async () => {
    if (!bulkMailSubject.trim() || !bulkMailBody.trim()) { showError('Subject and message are required.', 'Missing fields'); return; }
    setBulkMailSending(true);
    try {
      const items = candidates
        .filter((c: any) => selectedCardIds.includes(c.id))
        .map((c: any) => ({
          id: c.id,
          subject: bulkMailSubject.replaceAll('{name}', c.full_name || 'Candidate'),
          message: bulkMailBody.replaceAll('{name}', c.full_name || 'Candidate'),
        }));
      const r = (await api.post('/candidates/notify-bulk/', { channels: ['EMAIL'], items })) as any;
      const d = r?.data || {};
      if ((d.failed ?? 0) > 0) toast.warn(r?.message || 'Some mails failed.');
      else toast.success(r?.message || 'Mails sent ✓');
      setBulkMailOpen(false);
      setSelectedCardIds([]);
    } catch (err: any) {
      showError(err?.message || 'Send failed.', 'Error');
    } finally {
      setBulkMailSending(false);
    }
  };
  const [selectedCandidate, setSelectedCandidate] = useState<any | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [isFormOpen, setIsFormOpen] = useState(false);
  const [formMode, setFormMode] = useState<'create' | 'edit'>('create');
  const [editingCandidateId, setEditingCandidateId] = useState<number | null>(null);
  const [usersList, setUsersList] = useState<any[]>([]);
  const [usersError, setUsersError] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [formErrors, setFormErrors] = useState<any>({});
  const [formErrorList, setFormErrorList] = useState<string[]>([]);

  const [activeFormTab, setActiveFormTab] = useState<'personal' | 'academic' | 'experience' | 'projects' | 'references'>('personal');
  const [smsModalOpen, setSmsModalOpen] = useState(false);

  const initialFormState = {
    user_id: '',
    first_name: '',
    last_name: '',
    email: '',
    phone_number: '',
    alternate_phone_number: '',
    date_of_birth: '',
    gender: '',
    city: '',
    state: '',
    country: '',
    current_address: '',
    permanent_address: '',
    fresher: true,
    total_experience: '',
    employment_type: '',
    current_company: '',
    previous_company: '',
    current_role: '',
    current_ctc: '',
    expected_ctc: '',
    notice_period: '',
    notice_period_id: '',
    current_location: '',
    preferred_location: '',
    highest_qualification: '',
    university: '',
    college: '',
    passing_year: '',
    percentage_cgpa: '',
    skills: '',
    languages: '',
    linkedin: '',
    github: '',
    portfolio: '',
    personal_website: '',
    availability: 'Immediate',
    status: 'Draft',
    professional_summary: '',
    resume: '',
  };

  const [formData, _setFormData] = useState(initialFormState);
  const [selectedJobIds, setSelectedJobIds] = useState<number[]>([]);
  const [jobOptions, setJobOptions] = useState<{ value: number; label: string; title: string; company: string; status: string }[]>([]);
  const [jobPickerSearch, setJobPickerSearch] = useState('');
  const [editedFields, setEditedFields] = useState<Set<string>>(new Set());
  const [isDragging, setIsDragging] = useState(false);
  const [isParsing, setIsParsing] = useState(false);
  const [parsingProgress, setParsingProgress] = useState(0);
  const [uploadedFileName, setUploadedFileName] = useState('');

  // Location management states
  const [designationOptions, setDesignationOptions] = useState<{ value: string; label: string }[]>([]);
  const [countries, setCountries] = useState<{ id: number; name: string; iso2: string }[]>([]);
  const [states, setStates] = useState<{ id: number; name: string }[]>([]);
  const [cities, setCities] = useState<{ id: number; name: string }[]>([]);
  const [selectedCountryId, setSelectedCountryId] = useState<number | null>(null);
  const [selectedStateId, setSelectedStateId] = useState<number | null>(null);
  const [loadingLocations, setLoadingLocations] = useState(false);

  // Intercept state changes to track which fields the user has manually edited
  const setFormData = (value: any) => {
    if (typeof value === 'function') {
      _setFormData((prev: any) => {
        const next = value(prev);
        const changed = Object.keys(next).filter((k) => next[k] !== prev[k]);
        if (changed.length > 0) {
          setEditedFields((prevEdited) => {
            const nextEdited = new Set(prevEdited);
            changed.forEach((f) => nextEdited.add(f));
            return nextEdited;
          });
        }
        return next;
      });
    } else {
      _setFormData((prev: any) => {
        const next = { ...prev, ...value };
        const changed = Object.keys(next).filter((k) => next[k] !== prev[k]);
        if (changed.length > 0) {
          setEditedFields((prevEdited) => {
            const nextEdited = new Set(prevEdited);
            changed.forEach((f) => nextEdited.add(f));
            return nextEdited;
          });
        }
        return next;
      });
    }
  };

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(true);
  };

  const handleDragLeave = () => {
    setIsDragging(false);
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    const files = e.dataTransfer.files;
    if (files && files.length > 0) {
      processResumeFile(files[0]);
    }
  };

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      processResumeFile(files[0]);
    }
  };

  const processResumeFile = async (file: File) => {
    const ext = (file.name.split('.').pop() || '').toLowerCase();
    if (ext !== 'pdf' || (file.type && file.type !== 'application/pdf')) {
      toast.error(`Unsupported file type ".${ext || 'unknown'}". Only PDF resumes are supported.`);
      return;
    }
    if (file.size === 0) {
      toast.error('This file is empty. Please choose a valid resume PDF.');
      return;
    }
    if (file.size > 5 * 1024 * 1024) {
      toast.error(`File is too large (${(file.size / 1024 / 1024).toFixed(1)} MB). Maximum allowed is 5 MB.`);
      return;
    }

    setUploadedFileName(file.name);
    setIsParsing(true);
    setParsingProgress(10);

    // Simulate progress bar movement
    const progressInterval = setInterval(() => {
      setParsingProgress((prev) => {
        if (prev >= 90) {
          clearInterval(progressInterval);
          return 90;
        }
        return prev + 15;
      });
    }, 200);

    try {
      const formDataObj = new FormData();
      formDataObj.append('file', file);
      if (editingCandidateId) {
        formDataObj.append('candidate_id', String(editingCandidateId));
      } else if (formData.user_id) {
        formDataObj.append('user_id', String(formData.user_id));
      }

      const result = (await api.upload('/candidates/upload-resume/', formDataObj)) as any;

      clearInterval(progressInterval);
      setParsingProgress(100);

      // Update form resume reference (relative path)
      _setFormData((prev: any) => ({ ...prev, resume: result.resume_path }));

      toast.success('Resume uploaded successfully!');

      if (result.success && result.parsed_data) {
        // Auto populate fields
        const parsed = { ...result.parsed_data };

        // --- Sanity checks: don't insert wrong data from a bad parse ---
        // Drop invalid email / phone instead of filling garbage.
        if (parsed.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(parsed.email).trim())) {
          delete parsed.email;
        }
        if (parsed.phone_number && String(parsed.phone_number).replace(/\D/g, '').length < 10) {
          delete parsed.phone_number;
        }
        // If the parser found nothing identifying (no name/email/phone), the file
        // is probably not a proper resume — attach it but skip auto-fill entirely.
        const identifying = !!(parsed.first_name || parsed.email || parsed.phone_number);
        if (!identifying) {
          toast.warn('Resume attached, but we couldn’t read valid details from it. Please fill the form manually.');
          return;
        }

        _setFormData((prev: any) => {
          const next = { ...prev };
          Object.keys(parsed).forEach((key) => {
            if (key in prev && parsed[key] !== undefined && parsed[key] !== null) {
              if (key === 'skills' || key === 'languages') {
                if (!editedFields.has(key)) {
                  next[key] = parsed[key];
                }
              } else if (key !== 'educations' && key !== 'experiences' && key !== 'projects' && key !== 'references') {
                if (!editedFields.has(key)) {
                  next[key] = parsed[key];
                }
              }
            }
          });
          return next;
        });

        // Populate dynamic lists
        if (parsed.experiences && parsed.experiences.length > 0) {
          setExperiences(parsed.experiences);
        }
        if (parsed.educations && parsed.educations.length > 0) {
          setEducations(parsed.educations);
        }
        if (parsed.projects && parsed.projects.length > 0) {
          setProjects(parsed.projects);
        }
        if (parsed.references && parsed.references.length > 0) {
          setReferences(parsed.references);
        }

        toast.success('Resume parsed successfully!');
      } else {
        toast.warn(result.message || 'Unable to parse resume. Please fill the form manually.');
      }
    } catch (err: any) {
      clearInterval(progressInterval);
      console.error(err);
      toast.error(err.message || 'Unable to parse resume. Please fill the form manually.');
    } finally {
      setIsParsing(false);
    }
  };

  const handleRemoveResume = async () => {
    const result = await showConfirmDelete(
      'Removing the resume will also reset the whole form. Continue?'
    );
    if (!result.isConfirmed) return;

    // Full reset — back to a blank Add Candidate form.
    setFormData(initialFormState);
    setExperiences([]);
    setEducations([]);
    setProjects([]);
    setReferences([]);
    setFormErrors({});
    setFormErrorList([]);
    setEditedFields(new Set());
    setUploadedFileName('');
    setParsingProgress(0);
    toast.info('Resume removed — form reset.');
  };


  const [experiences, setExperiences] = useState<any[]>([]);
  const [educations, setEducations] = useState<any[]>([]);
  const [projects, setProjects] = useState<any[]>([]);
  const [references, setReferences] = useState<any[]>([]);

  useEffect(() => {
    if (!user) return;
    // Gate on the actual RBAC permission (candidates.view_candidate) instead of a
    // hardcoded role whitelist — the old whitelist (ADMIN/RECRUITER/HIRING_MANAGER
    // only) silently excluded any other role granted this permission via Groups &
    // Permissions, e.g. PROJECT_MANAGER, kicking them back to /dashboard even
    // though the backend API and sidebar menu both correctly allowed them through.
    const canViewCandidates =
      user.role === 'ADMIN' || (user.permissions?.includes('candidates.view_candidate') ?? false);
    if (!canViewCandidates) {
      router.push('/dashboard');
    } else {
      loadDesignations();
      loadNoticePeriods();
      (api.get('/jobs/?page_size=500') as Promise<any>)
        .then((r) => {
          const data = r?.data?.results ?? r?.data ?? [];
          setJobOptions((Array.isArray(data) ? data : [])
            .filter((j: any) => j.status === 'Published')   // only live job orders are assignable
            .map((j: any) => ({
              value: j.id,
              label: `#${j.id} ${j.title}${j.client_name ? ` · ${j.client_name}` : ''}`,
              title: j.title,
              company: j.client_name || 'Internal',
              status: j.status || '',
            })));
        })
        .catch(() => { });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user]);

  // Build the server-side candidates query from the current page + every filter.
  const buildCandidateQuery = () => {
    const p = new URLSearchParams();
    p.set('page', String(pagination.pageIndex + 1));
    p.set('page_size', String(pagination.pageSize));
    if (search.trim()) p.set('search', search.trim());
    if (statusFilter !== 'ALL') p.set('status', statusFilter);
    if (experienceFilter !== 'ALL') p.set('experience', experienceFilter);
    if (sourceFilter !== 'ALL') p.set('source', sourceFilter);
    if (jobFilter.trim()) p.set('job', jobFilter.trim());
    const stateName = stateFilterId
      ? (filterStateOptions.find((o) => String(o.value) === stateFilterId)?.label || '')
      : '';
    if (stateName) p.set('state', stateName);
    if (cityFilters.length) p.set('cities', cityFilters.join(','));
    if (expYearsFilter) p.set('exp_years', expYearsFilter);
    if (expMonthsFilter) p.set('exp_months', expMonthsFilter);
    if (locationFilters.length) p.set('locations', locationFilters.join(','));
    if (companyFilters.length) p.set('companies', companyFilters.join(','));
    if (skillFilters.length) p.set('skills', skillFilters.join(','));
    if (salaryFrom) p.set('salary_from', salaryFrom);
    if (salaryTo) p.set('salary_to', salaryTo);
    if (designationFilters.length) p.set('designations', designationFilters.join(','));
    if (genderFilter !== 'ALL') p.set('gender', genderFilter);
    if (createdFrom) p.set('created_from', createdFrom);
    if (createdTo) p.set('created_to', createdTo);
    if (cardSort) p.set('ordering', cardSort);
    if (focusIds && focusIds.length > 0) p.set('ids', focusIds.join(','));
    if (pmMetric) p.set('pm_metric', pmMetric);
    if (stageCodes) p.set('stage_codes', stageCodes);
    if (ownerMe) p.set('owner', 'me');
    if (assignedMe) p.set('assigned', 'me');
    if (pmPeriod) p.set('period', pmPeriod);
    return p.toString();
  };

  // Export selected candidates (or the whole current page if none picked) to CSV.
  const exportCandidatesCsv = () => {
    const selectedIds = Object.keys(rowSelection).filter((k) => rowSelection[k]);
    const rows: any[] = selectedIds.length
      ? candidates.filter((c: any) => selectedIds.includes(String(c.id)))
      : candidates;
    if (!rows.length) { toast.info('No candidates to export.'); return; }
    const cols: [string, (c: any) => any][] = [
      ['ID', (c) => c.id],
      ['Name', (c) => c.full_name || `${c.first_name || ''} ${c.last_name || ''}`.trim()],
      ['Email', (c) => c.email || ''],
      ['Phone', (c) => c.phone_number || ''],
      ['Current Role', (c) => c.current_role || ''],
      ['Current Company', (c) => c.current_company || ''],
      ['Experience', (c) => (c.fresher ? 'Fresher' : (c.total_experience ?? ''))],
      ['Current CTC', (c) => c.current_ctc ?? ''],
      ['Expected CTC', (c) => c.expected_ctc ?? ''],
      ['Location', (c) => c.current_location || c.city || ''],
      ['Skills', (c) => (Array.isArray(c.skills) ? c.skills.join('; ') : (c.skills || ''))],
      ['Status', (c) => c.status || ''],
      ['Source', (c) => c.source || ''],
    ];
    const esc = (v: any) => {
      const s = String(v ?? '');
      return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
    };
    const csv = [cols.map((c) => c[0]).join(',')]
      .concat(rows.map((r) => cols.map((c) => esc(c[1](r))).join(',')))
      .join('\n');
    const blob = new Blob(['﻿' + csv], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `candidates_${new Date().toISOString().slice(0, 10)}.csv`;
    a.click();
    URL.revokeObjectURL(url);
    toast.success(`Exported ${rows.length} candidate${rows.length === 1 ? '' : 's'} to CSV.`);
  };

  const loadCandidates = async () => {
    setLoading(true);
    try {
      const q = buildCandidateQuery();
      const res = (await api.get(`/candidates/?${q}`)) as any;
      const data = res?.data ?? res;
      if (data && Array.isArray(data.results)) {
        setCandidates(data.results);
        setTotal(data.count ?? data.results.length);
      } else if (Array.isArray(data?.data)) {
        setCandidates(data.data);
        setTotal(data.data.length);
      } else if (Array.isArray(data)) {
        setCandidates(data);
        setTotal(data.length);
      } else {
        setCandidates([]);
        setTotal(0);
      }
    } catch (e) {
      console.error('Failed to load candidates', e);
    } finally {
      setLoading(false);
    }
  };

  // One key covering every filter — changing any of them resets to page 1 and refetches.
  const candFilterKey = JSON.stringify([
    search, statusFilter, experienceFilter, sourceFilter, jobFilter, stateFilterId, cityFilters,
    expYearsFilter, expMonthsFilter, locationFilters, companyFilters, skillFilters,
    salaryFrom, salaryTo, designationFilters, genderFilter, createdFrom, createdTo, cardSort, focusIds, pmMetric,
    stageCodes, ownerMe, assignedMe, pmPeriod,
  ]);

  const prevFilterKey = useRef(candFilterKey);
  useEffect(() => {
    if (prevFilterKey.current !== candFilterKey) {
      prevFilterKey.current = candFilterKey;
      if (pagination.pageIndex !== 0) {
        setPagination((p) => ({ ...p, pageIndex: 0 }));
      }
    }
  }, [candFilterKey, pagination.pageIndex]);

  useEffect(() => {
    if (!user) return;
    const t = setTimeout(() => { loadCandidates(); }, 250);
    return () => clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user, pagination.pageIndex, pagination.pageSize, candFilterKey]);

  const [asyncUsersLoading, setAsyncUsersLoading] = useState(false);
  const loadUsersList = async () => {
    setAsyncUsersLoading(true);
    try {
      const res = await api.get('/users/admin/users/?role=CANDIDATE') as any;
      setUsersList(res.data?.results || []);
    } catch (e) {
      console.error('Failed to load users list', e);
      setUsersError(true);
    } finally {
      setAsyncUsersLoading(false);
    }
  };

  const handleUserSearch = async (query: string) => {
    setAsyncUsersLoading(true);
    try {
      const res = await api.get(`/users/admin/users/?role=CANDIDATE&search=${encodeURIComponent(query)}`) as any;
      setUsersList(res.data?.results || []);
    } catch (e) {
      console.error('Failed to search users', e);
    } finally {
      setAsyncUsersLoading(false);
    }
  };

  const handleInspectCandidate = async (id: number) => {
    setDetailLoading(true);
    try {
      const res = await api.get(`/candidates/${id}/`) as any;
      setSelectedCandidate(res?.data?.data ?? res?.data ?? null);
    } catch (e) {
      console.error('Failed to load candidate details', e);
    } finally {
      setDetailLoading(false);
    }
  };

  const handleDeleteCandidate = (id: number) => {
    showConfirmDelete('Are you sure you want to delete this candidate profile?', async () => {
      try {
        await api.delete(`/candidates/${id}/`);
        setSelectedCandidate(null);
        loadCandidates();
      } catch (err) {
        toast.error(err instanceof Error ? err.message : 'Failed to delete candidate');
      }
    });
  };

  const [bulkUploading, setBulkUploading] = useState(false);
  const [bulkModalOpen, setBulkModalOpen] = useState(false);
  const [bulkTab, setBulkTab] = useState<'excel' | 'resumes'>('excel');
  const [bulkDragOver, setBulkDragOver] = useState(false);
  const [pendingBulkFile, setPendingBulkFile] = useState<File | null>(null);
  // Which file picker fed the current pendingBulkFile — the Bulk Candidate
  // import row, or the Bulk Notification modal's CSV import row. Lets
  // "Cancel / Choose Another File" reopen the SAME picker it came from.
  const [pendingBulkSource, setPendingBulkSource] = useState<'bulk_candidate' | 'notification'>('bulk_candidate');
  const bulkFileInputRef = useRef<HTMLInputElement | null>(null);
  const smsCsvInputRef = useRef<HTMLInputElement | null>(null);
  // Candidates from the LAST uploaded Excel — the mail/SMS modal works on these only,
  // never the whole candidate database.
  const [uploadedCandidateIds, setUploadedCandidateIds] = useState<number[]>([]);
  // The actual uploaded candidate objects, fetched by id. Kept separate from the
  // paginated `candidates` page state — otherwise the modal's "Pending" list is
  // empty whenever the uploaded rows aren't on the current page.
  const [uploadedCandidates, setUploadedCandidates] = useState<CandidateListItem[]>([]);

  // Fetch the uploaded candidates by id (server-side `ids` filter) so the SMS
  // modal shows them regardless of the current pagination page.
  const loadUploadedCandidates = async (ids: number[]) => {
    if (!ids.length) { setUploadedCandidates([]); return; }
    try {
      const p = new URLSearchParams();
      p.set('ids', ids.join(','));
      p.set('page_size', String(Math.min(ids.length, 500)));
      const res = (await api.get(`/candidates/?${p.toString()}`)) as any;
      const data = res?.data ?? res;
      const rows = Array.isArray(data?.results) ? data.results
        : Array.isArray(data?.data) ? data.data
        : Array.isArray(data) ? data : [];
      setUploadedCandidates(rows);
    } catch (e) {
      console.error('Failed to load uploaded candidates', e);
      setUploadedCandidates([]);
    }
  };

  // --- Comment / Remarks history modal (per candidate) ---
  const [commentCandidate, setCommentCandidate] = useState<any | null>(null);
  const [commentList, setCommentList] = useState<{ id: number; comment: string; by: string | null; created_at: string }[]>([]);
  const [commentLoading, setCommentLoading] = useState(false);
  const [commentText, setCommentText] = useState('');
  const [commentAdding, setCommentAdding] = useState(false);
  const [commentSearch, setCommentSearch] = useState('');

  const loadCommentHistory = async (candidateId: number) => {
    setCommentLoading(true);
    try {
      const r = (await api.get(`/candidates/${candidateId}/comments/`)) as any;
      setCommentList(r?.data ?? []);
    } catch { setCommentList([]); }
    finally { setCommentLoading(false); }
  };

  const openCommentModal = (candidate: any) => {
    setCommentCandidate(candidate);
    setCommentText('');
    setCommentSearch('');
    setCommentList([]);
    loadCommentHistory(candidate.id);
  };

  const addCommentFromList = async () => {
    if (!commentCandidate || !commentText.trim()) return;
    setCommentAdding(true);
    try {
      await api.post(`/candidates/${commentCandidate.id}/comments/`, { comment: commentText.trim() });
      setCommentText('');
      loadCommentHistory(commentCandidate.id);
      toast.success('Remark added');
    } catch (err: any) {
      showError(err?.message || 'Could not add remark.', 'Error');
    } finally {
      setCommentAdding(false);
    }
  };

  // --- Single-candidate Notify modal ---
  const [notifyCandidate, setNotifyCandidate] = useState<any | null>(null);

  const openNotifyModal = async (candidate: any) => {
    setNotifyCandidate(candidate);
  };

  // Load master designations for the Current Role dropdown
  const loadDesignations = async () => {
    try {
      const names: string[] = [];
      let page = 1;
      let hasNext = true;
      while (hasNext && page <= 10) {
        const res = (await api.get(`/master-designation?page_size=100&page=${page}`)) as any;
        const data = res?.data;
        const results = Array.isArray(data) ? data : data?.results || [];
        results.forEach((d: any) => {
          if (d?.name) names.push(d.name);
        });
        hasNext = Boolean(data?.next);
        page += 1;
      }
      const unique = Array.from(new Set(names)).sort((a, b) => a.localeCompare(b));
      setDesignationOptions(unique.map((name) => ({ value: name, label: name })));
    } catch (err) {
      console.error('Failed to load designations', err);
      setDesignationOptions([]);
    }
  };

  // ---- Card-view filter data: JD locations (+counts), clients, master skills ----
  const loadJdLocations = async () => {
    setJdLocationsLoading(true);
    try {
      const counts = new Map<string, { name: string; count: number }>();
      let page = 1;
      let hasNext = true;
      while (hasNext && page <= 10) {
        const res = (await api.get(`/jobs/?page_size=100&page=${page}`)) as any;
        const data = res?.data;
        const results = Array.isArray(data) ? data : data?.results || [];
        results.forEach((j: any) => {
          String(j?.location || '')
            .split(/[,/|]/)
            .map((t: string) => t.trim())
            .filter(Boolean)
            .forEach((loc: string) => {
              const key = loc.toLowerCase();
              const cur = counts.get(key);
              if (cur) cur.count += 1;
              else counts.set(key, { name: loc, count: 1 });
            });
        });
        hasNext = Boolean(data?.next);
        page += 1;
      }
      setJdLocations(Array.from(counts.values()).sort((a, b) => b.count - a.count || a.name.localeCompare(b.name)));
    } catch (err) {
      console.error('Failed to load JD locations', err);
      setJdLocations([]);
    } finally {
      setJdLocationsLoading(false);
    }
  };

  const loadClientOptions = async () => {
    setClientsLoading(true);
    try {
      const names: string[] = [];
      let page = 1;
      let hasNext = true;
      while (hasNext && page <= 10) {
        const res = (await api.get(`/clients/?page_size=100&page=${page}`)) as any;
        const data = res?.data;
        const results = Array.isArray(data) ? data : data?.results || [];
        results.forEach((c: any) => {
          if (c?.name) names.push(c.name);
        });
        hasNext = Boolean(data?.next);
        page += 1;
      }
      const unique = Array.from(new Set(names)).sort((a, b) => a.localeCompare(b));
      setClientOptions(unique.map((n) => ({ value: n, label: n })));
    } catch (err) {
      console.error('Failed to load clients', err);
      setClientOptions([]);
    } finally {
      setClientsLoading(false);
    }
  };

  const loadMasterSkillOptions = async () => {
    setMasterSkillsLoading(true);
    try {
      const res = (await api.get('/public/skills/')) as any;
      const data = res?.data ?? [];
      const list = Array.isArray(data) ? data : data?.results || [];
      const unique = Array.from(new Set(list.map((s: any) => s?.name).filter(Boolean))) as string[];
      setMasterSkillOptions(unique.sort((a, b) => a.localeCompare(b)).map((n) => ({ value: n, label: n })));
    } catch (err) {
      console.error('Failed to load master skills', err);
      setMasterSkillOptions([]);
    } finally {
      setMasterSkillsLoading(false);
    }
  };

  // Fetch the dynamic filter data once, the first time the card view or the
  // table filter panel is opened.
  useEffect(() => {
    if (cardMastersLoaded || (viewMode !== 'cards' && !filterOpen)) return;
    setCardMastersLoaded(true);
    loadJdLocations();
    loadClientOptions();
    loadMasterSkillOptions();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [viewMode, filterOpen, cardMastersLoaded]);



  // Validation handlers for names
  const handleFirstNameChange = (value: string) => {
    const sanitized = value.replace(/[^A-Za-z\s]/g, '');
    setFormData({ ...formData, first_name: sanitized });
  };

  const handleLastNameChange = (value: string) => {
    const sanitized = value.replace(/[^A-Za-z\s]/g, '');
    setFormData({ ...formData, last_name: sanitized });
  };

  // Validation handlers for phone numbers
  const handlePhoneChange = (value: string) => {
    const sanitized = value.replace(/\D/g, '').slice(0, 10);
    setFormData({ ...formData, phone_number: sanitized });
  };

  const handleAlternatePhoneChange = (value: string) => {
    const sanitized = value.replace(/\D/g, '').slice(0, 10);
    setFormData({ ...formData, alternate_phone_number: sanitized });
  };

  const [noticePeriodOptions, setNoticePeriodOptions] = useState<{ id: number; value: number; label: string }[]>([]);

  const loadNoticePeriods = async () => {
    try {
      const res = (await api.get('/public/notice-periods/')) as any;
      const items = res?.data?.results || res?.results || res?.data || (Array.isArray(res) ? res : []);
      if (items && items.length) {
        setNoticePeriodOptions(items);
      } else {
        const fallback = (await api.get('/master-data/notice-periods/?page_size=500')) as any;
        const fItems = fallback?.data?.results || fallback?.results || fallback?.data || (Array.isArray(fallback) ? fallback : []);
        setNoticePeriodOptions(fItems);
      }
    } catch {
      try {
        const fallback = (await api.get('/master-data/notice-periods/?page_size=500')) as any;
        const fItems = fallback?.data?.results || fallback?.results || fallback?.data || (Array.isArray(fallback) ? fallback : []);
        setNoticePeriodOptions(fItems);
      } catch (e) {
        console.error('Failed to load notice periods master data', e);
      }
    }
  };

  const handleFilterStateChange = (id: string) => {
    setStateFilterId(id);
    setCityFilters([]);
  };

  // Handle country selection
  const handleCountryChange = (countryId: number | null) => {
    if (!countryId) {
      setSelectedCountryId(null);
      setFormData({ ...formData, country: '' });
      setSelectedStateId(null);
      return;
    }
    const country = countries.find((c) => c.id === countryId);
    setSelectedCountryId(countryId);
    setFormData({ ...formData, country: country?.name || '' });
  };

  // Handle state selection
  const handleStateChange = (stateId: number | null) => {
    if (!stateId) {
      setSelectedStateId(null);
      setFormData({ ...formData, state: '' });
      return;
    }
    const state = states.find((s) => s.id === stateId);
    setSelectedStateId(stateId);
    setFormData({ ...formData, state: state?.name || '' });
  };

  // Handle city selection
  const handleCityChange = (cityId: number | null) => {
    if (!cityId) {
      setFormData({ ...formData, city: '' });
      return;
    }
    const city = cities.find((c) => c.id === cityId);
    setFormData({ ...formData, city: city?.name || '' });
  };


  // Stage the picked file for preview + confirmation — the actual upload
  // (handleBulkUpload) only runs after the user confirms in the modal.
  const stageBulkUpload = (file: File, source: 'bulk_candidate' | 'notification' = 'bulk_candidate') => {
    if (!/\.(csv|xlsx)$/i.test(file.name)) { showError('Please choose a .xlsx or .csv file.', 'Invalid file'); return; }
    setPendingBulkSource(source);
    setPendingBulkFile(file);
  };

  const handleBulkUpload = async (file: File) => {
    if (!/\.(csv|xlsx)$/i.test(file.name)) { showError('Please choose a .xlsx or .csv file.', 'Invalid file'); return; }
    setBulkUploading(true);
    try {
      const fd = new FormData();
      fd.append('file', file);
      const json = (await api.upload('/candidates/bulk-upload/', fd)) as any;
      const d = json.data || {};
      if (Array.isArray(d.candidate_ids)) {
        setUploadedCandidateIds(d.candidate_ids);
        loadUploadedCandidates(d.candidate_ids);
      }
      setBulkModalOpen(false);
      showImportSummary({
        created: d.created ?? 0,
        updated: d.updated ?? 0,
        pipeline: d.pipeline_entries ?? 0,
        skipped: d.skipped ?? 0,
        reasons: d.errors ?? [],
      });
      loadCandidates();
    } catch (err) {
      showError(err instanceof Error ? err.message : 'Bulk upload failed', 'Error');
    } finally {
      setBulkUploading(false);
    }
  };

  // SRC-004: bulk multi-CV (PDF/DOCX) upload — parse each, create candidates.
  const handleBulkCVUpload = async (files: FileList | File[]) => {
    const list = Array.from(files).filter((f) => /\.(pdf|docx)$/i.test(f.name));
    if (!list.length) { showError('Please choose PDF or DOCX CV files.', 'Invalid files'); return; }
    setBulkUploading(true);
    try {
      const fd = new FormData();
      list.forEach((f) => fd.append('files', f));
      const json = (await api.upload('/candidates/bulk-cv-upload/', fd)) as any;
      const d = json.data || {};
      setBulkModalOpen(false);
      const reasons = (d.results || [])
        .filter((r: any) => r.status !== 'CREATED')
        .map((r: any) => `${r.file}: ${r.status}${r.reason ? ` — ${r.reason}` : ''}`);
      showImportSummary({
        created: d.created ?? 0,
        pipeline: 0,
        skipped: d.skipped ?? 0,
        reasons,
        title: 'CV Import complete',
      });
      loadCandidates();
    } catch (err) {
      showError(err instanceof Error ? err.message : 'CV upload failed', 'Error');
    } finally {
      setBulkUploading(false);
    }
  };

  const handleStartCreate = () => {
    router.push('/candidates/add');
  };

  const startEditWith = (cand: any) => {
    if (!cand) return;
    setFormErrors({});
    setFormErrorList([]);
    setFormMode('edit');
    setEditingCandidateId(cand.id);
    setFormData({
      user_id: cand.user?.id || cand.user_id || '',
      first_name: cand.first_name || '',
      last_name: cand.last_name || '',
      phone_number: cand.phone_number || '',
      alternate_phone_number: cand.alternate_phone_number || '',
      date_of_birth: cand.date_of_birth || '',
      gender: cand.gender || '',
      city: cand.city || '',
      state: cand.state || '',
      country: cand.country || '',
      current_address: cand.current_address || '',
      permanent_address: cand.permanent_address || '',
      fresher: cand.fresher ?? true,
      total_experience: cand.total_experience || '',
      employment_type: cand.employment_type || '',
      current_company: cand.current_company || '',
      previous_company: cand.previous_company || '',
      current_role: cand.current_role || '',
      current_ctc: cand.current_ctc || '',
      expected_ctc: cand.expected_ctc || '',
      notice_period: cand.notice_period || '',
      notice_period_id: cand.notice_period_id || cand.notice_period_ref_id || '',
      current_location: cand.current_location || '',
      preferred_location: cand.preferred_location || '',
      highest_qualification: cand.highest_qualification || '',
      university: cand.university || '',
      college: cand.college || '',
      passing_year: cand.passing_year || '',
      percentage_cgpa: cand.percentage_cgpa || '',
      skills: cand.skills ? cand.skills.join(', ') : '',
      languages: cand.languages ? cand.languages.join(', ') : '',
      linkedin: cand.linkedin || '',
      github: cand.github || '',
      portfolio: cand.portfolio || '',
      personal_website: cand.personal_website || '',
      availability: cand.availability || 'Immediate',
      status: cand.status || 'Draft',
      professional_summary: cand.professional_summary || '',
      resume: cand.resume || '',
      resume_url: cand.resume_url || '',
    });
    setExperiences(cand.experiences || []);
    setEducations(cand.educations || []);
    setProjects(cand.projects || []);
    setReferences(cand.references || []);
    // Prefill the job picker with the JDs already assigned to this candidate.
    setSelectedJobIds(Array.isArray(cand.assigned_job_ids) ? cand.assigned_job_ids.map((x: any) => Number(x)) : []);
    setUploadedFileName(cand.resume ? cand.resume.split('/').pop() : '');
    setEditedFields(new Set());
    setIsFormOpen(true);
    setSelectedCandidate(null);
  };

  const handleStartEdit = () => startEditWith(selectedCandidate);

  // Deep-link: /candidates?edit=<id> (e.g. from the candidate detail page)
  // fetches that candidate and opens the edit form.
  const editParamHandled = useRef(false);
  useEffect(() => {
    if (editParamHandled.current) return;
    const editId = typeof window !== 'undefined'
      ? new URLSearchParams(window.location.search).get('edit')
      : null;
    if (!editId || !user) return;
    editParamHandled.current = true;
    (async () => {
      try {
        const res = (await api.get(`/candidates/${editId}/`)) as any;
        const cand = res?.data?.data ?? res?.data ?? null;
        if (cand) startEditWith(cand);
      } catch { /* ignore — candidate not found / no access */ }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user]);

  const handleSubmitCandidate = async (e: React.FormEvent) => {
    e.preventDefault();
    setSubmitting(true);
    setFormErrors({});

    const parsedSkills = formData.skills
      ? formData.skills.split(',').map((s) => s.trim()).filter(Boolean)
      : [];
    const parsedLanguages = formData.languages
      ? formData.languages.split(',').map((l) => l.trim()).filter(Boolean)
      : [];

    const payload: any = {
      ...formData,
      skills: parsedSkills,
      languages: parsedLanguages,
      experiences: experiences.map(exp => ({
        ...exp,
        current_ctc: exp.current_ctc === '' ? null : Number(exp.current_ctc),
        expected_ctc: exp.expected_ctc === '' ? null : Number(exp.expected_ctc),
        notice_period: exp.notice_period === '' ? null : Number(exp.notice_period),
      })),
      educations: educations
        // Only submit rows that have ALL required fields (degree, institution, passing year).
        // Incomplete rows (e.g. from resume parsing) are dropped rather than blocking the save.
        .filter(edu =>
          (edu.degree_name || '').trim() &&
          (edu.institution_name || '').trim() &&
          String(edu.passing_year || '').trim()
        )
        .map(edu => ({
          ...edu,
          passing_year: edu.passing_year === '' ? null : Number(edu.passing_year),
        })),
      projects,
      references,
      total_experience: formData.total_experience === '' ? null : Number(formData.total_experience),
      current_ctc: formData.current_ctc === '' ? null : Number(formData.current_ctc),
      expected_ctc: formData.expected_ctc === '' ? null : Number(formData.expected_ctc),
      notice_period: formData.notice_period === '' ? null : Number(formData.notice_period),
      notice_period_id: formData.notice_period_id === '' ? null : Number(formData.notice_period_id),
      passing_year: formData.passing_year === '' ? null : Number(formData.passing_year),
    };

    if (!payload.user_id) {
      delete payload.user_id;
    } else {
      payload.user_id = Number(payload.user_id);
    }

    // Assign to one or more Job Orders (create AND edit — backend is additive
    // and de-dupes, so re-sending already-assigned jobs is safe).
    if (selectedJobIds.length) {
      payload.job_ids = selectedJobIds.map((j) => Number(j));
    }

    try {
      if (formMode === 'create') {
        await api.post('/candidates/', payload);
        showSuccess('Candidate profile created successfully!');
      } else {
        await api.put(`/candidates/${editingCandidateId}/`, payload);
        showSuccess('Candidate profile updated successfully!');
      }
      setFormErrors({});
      setFormErrorList([]);
      setIsFormOpen(false);
      loadCandidates();
    } catch (err: any) {
      console.error(err);
      const fieldErrors = err?.data?.errors;
      if (fieldErrors && typeof fieldErrors === 'object') {
        setFormErrors(fieldErrors);
        // Recursively flatten nested DRF errors (arrays of objects, dicts) into readable "field: message" lines.
        const flatten = (val: any, prefix = ''): string[] => {
          if (val == null) return [];
          if (typeof val === 'string') return [prefix ? `${prefix}: ${val}` : val];
          if (Array.isArray(val)) return val.flatMap((v, i) =>
            (v && typeof v === 'object') ? flatten(v, prefix ? `${prefix}[${i + 1}]` : `#${i + 1}`) : flatten(v, prefix));
          if (typeof val === 'object') return Object.entries(val)
            .flatMap(([k, v]) => flatten(v, prefix ? `${prefix}.${k}` : k));
          return [prefix ? `${prefix}: ${String(val)}` : String(val)];
        };
        const all = flatten(fieldErrors);
        setFormErrorList(all);
        showError(all.slice(0, 6).join('\n'), 'Please fix the following');
      } else {
        setFormErrorList([err?.message || 'An unexpected error occurred.']);
        showError(err?.message || 'An unexpected error occurred.', 'Error');
      }
    } finally {
      setSubmitting(false);
    }
  };

  const addExperience = () => {
    setExperiences([
      ...experiences,
      {
        company_name: '',
        role: '',
        joining_date: '',
        last_working_date: '',
        is_current_company: false,
        current_ctc: '',
        expected_ctc: '',
        notice_period: '',
        achievements: '',
        responsibilities: '',
        reason_for_leaving: '',
      },
    ]);
  };
  const removeExperience = (index: number) => setExperiences(experiences.filter((_, i) => i !== index));
  const updateExperience = (index: number, key: string, value: any) => {
    const updated = [...experiences];
    updated[index][key] = value;
    setExperiences(updated);
  };

  const addEducation = () => {
    setEducations([
      ...educations,
      {
        degree_name: '',
        field_of_study: '',
        institution_name: '',
        passing_year: '',
        percentage_cgpa: '',
      },
    ]);
  };
  const removeEducation = (index: number) => setEducations(educations.filter((_, i) => i !== index));
  const updateEducation = (index: number, key: string, value: any) => {
    const updated = [...educations];
    updated[index][key] = value;
    setEducations(updated);
  };

  const addProject = () => {
    setProjects([
      ...projects,
      {
        project_name: '',
        description: '',
        technologies_used: '',
        duration: '',
        role: '',
      },
    ]);
  };
  const removeProject = (index: number) => setProjects(projects.filter((_, i) => i !== index));
  const updateProject = (index: number, key: string, value: any) => {
    const updated = [...projects];
    updated[index][key] = value;
    setProjects(updated);
  };

  const addReference = () => {
    setReferences([
      ...references,
      {
        name: '',
        company: '',
        designation: '',
        email: '',
        phone: '',
        relationship: '',
      },
    ]);
  };
  const removeReference = (index: number) => setReferences(references.filter((_, i) => i !== index));
  const updateReference = (index: number, key: string, value: any) => {
    const updated = [...references];
    updated[index][key] = value;
    setReferences(updated);
  };

  const renderError = (field: string) => {
    if (formErrors && formErrors[field]) {
      return (
        <p className="text-rose-500 text-[10px] font-bold mt-1">
          {Array.isArray(formErrors[field]) ? formErrors[field].join(', ') : formErrors[field]}
        </p>
      );
    }
    return null;
  };

  const columns = [
    {
      id: 'select',
      enableSorting: false,
      header: ({ table }: any) => (
        <input
          type="checkbox"
          aria-label="Select all candidates"
          checked={table.getIsAllPageRowsSelected()}
          ref={(el: HTMLInputElement | null) => { if (el) el.indeterminate = !table.getIsAllPageRowsSelected() && table.getIsSomePageRowsSelected(); }}
          onChange={table.getToggleAllPageRowsSelectedHandler()}
          className="w-4 h-4 accent-[#405189] cursor-pointer"
        />
      ),
      cell: ({ row }: any) => (
        <input
          type="checkbox"
          aria-label="Select candidate"
          checked={row.getIsSelected()}
          onChange={row.getToggleSelectedHandler()}
          onClick={(e) => e.stopPropagation()}
          className="w-4 h-4 accent-[#405189] cursor-pointer"
        />
      ),
    },
    {
      id: 'srNo',
      header: 'S.No.',
      cell: ({ row, table }: any) => {
        const pageIndex = table.getState().pagination.pageIndex;
        const pageSize = table.getState().pagination.pageSize;
        return <span className="font-semibold text-slate-500 dark:text-slate-400">{pageIndex * pageSize + row.index + 1}</span>;
      },
    },
    {
      accessorKey: 'full_name',
      header: 'Name',
      cell: ({ row }: any) => {
        const c = row.original;
        return (
          <div className="min-w-[220px]">
            <div className="flex items-center gap-2">
              <a href={`/candidates/${c.id}`} target="_blank" rel="noreferrer" title="View profile (new tab)"
                className="w-6 h-6 shrink-0 rounded-none flex items-center justify-center text-slate-400 hover:text-[#405189] hover:bg-slate-100 dark:hover:bg-slate-800 transition">
                <i className="fa-solid fa-eye text-[12px]"></i>
              </a>
              <a href={`/candidates/${c.id}`} target="_blank" rel="noreferrer"
                className="font-extrabold text-[#405189] hover:underline text-sm text-left whitespace-nowrap">{c.full_name}</a>
            </div>
          </div>
        );
      },
    },
    { accessorKey: 'city', header: 'City', cell: ({ row }: any) => <span className="text-slate-600 dark:text-slate-300">{row.original.city || '—'}</span> },
    { accessorKey: 'state', header: 'State', cell: ({ row }: any) => <span className="text-slate-600 dark:text-slate-300">{row.original.state || '—'}</span> },
    {
      accessorKey: 'source',
      header: 'Source',
      cell: ({ row }: any) => {
        const s = String(row.original.source ?? '').trim().toUpperCase();
        // No meaningful attribution (OTHER / null / blank) → plain dash, styled
        // like the City/State columns instead of an "Other" badge.
        if (isSourceEmpty(s)) {
          return <span className="text-slate-600 dark:text-slate-300">{SOURCE_EMPTY}</span>;
        }
        const CLS: Record<string, string> = {
          SELF: 'bg-[#405189]/10 text-[#405189]',
          LINKEDIN: 'bg-[#0a66c2]/10 text-[#0a66c2]',
          NAUKRI: 'bg-[#4a90d9]/10 text-[#2f6fb0]',
          UPLOAD: 'bg-[#0ab39c]/10 text-[#0ab39c]',
          REFERRAL: 'bg-amber-500/10 text-amber-600',
          WHATSAPP: 'bg-green-500/10 text-green-600 dark:text-green-400',
          SMS: 'bg-orange-500/10 text-orange-600 dark:text-orange-400',
          TELEGRAM: 'bg-sky-500/10 text-sky-600 dark:text-sky-400',
          EMAIL: 'bg-teal-500/10 text-teal-600 dark:text-teal-400',
          DIRECT: 'bg-indigo-500/10 text-indigo-600 dark:text-indigo-400',
        };
        const cls = CLS[s] || 'bg-slate-100 text-slate-500 dark:bg-slate-800 dark:text-slate-400';
        return <span className={`text-[10px] font-bold px-2 py-0.5 ${cls}`}>{sourceLabel(s)}</span>;
      },
    },
    {
      id: 'skills',
      header: 'Key Skills',
      cell: ({ row }: any) => {
        const s: string[] = row.original.skills || [];
        return s.length ? (
          // hover/touch shows the FULL skill list as a tooltip
          <div className="flex flex-wrap items-center gap-1 min-w-[260px] cursor-default" title={s.join(', ')}>
            {s.slice(0, 3).map((x) => <span key={x} className="text-[11px] font-semibold bg-[#405189]/10 text-[#405189] px-2 py-0.5 rounded-none whitespace-nowrap">{x}</span>)}
            {s.length > 3 && <span className="text-[11px] font-bold text-[#405189]">+{s.length - 3} more</span>}
          </div>
        ) : <span className="text-slate-400">—</span>;
      },
    },
    {
      id: "telegram_id",
      header: "telegram_id",
      cell: ({ row }: any) => <span className="text-slate-600 dark:text-slate-300">{row.original.telegram_chat_id || '—'}</span>,
    },
    { accessorKey: 'created_at', header: 'Created', cell: ({ row }: any) => <span className="text-slate-500 whitespace-nowrap">{formatDate(row.original.created_at)}</span> },
    { accessorKey: 'updated_at', header: 'Updated', cell: ({ row }: any) => <span className="text-slate-500 whitespace-nowrap">{formatDate(row.original.updated_at)}</span> },
    {
      id: 'actions',
      header: () => <div className="text-right">Action</div>,
      cell: ({ row }: any) => {
        const c = row.original;
        const resumePath = c.resume_url || c.resume;
        const hasResume = Boolean(resumePath && String(resumePath).trim() !== '');
        const actionBtn = 'w-8 h-8 flex items-center justify-center border transition';
        return (
          <div className="flex items-center justify-end gap-1.5">
            <button
              onClick={() => hasResume && setResumeView({ url: resumePath, name: `${c.full_name} — Resume` })}
              disabled={!hasResume}
              title={hasResume ? 'Preview Resume' : 'No resume uploaded'}
              className={`${actionBtn} ${hasResume
                ? 'border-[#f06548]/30 bg-[#f06548]/10 text-[#f06548] hover:bg-[#f06548] hover:text-white cursor-pointer'
                : 'border-slate-200 dark:border-slate-800 bg-slate-100 dark:bg-slate-800/40 text-slate-400 dark:text-slate-600 opacity-50 cursor-not-allowed'
                }`}
            >
              <i className="fa-solid fa-file-pdf text-[13px]"></i>
            </button>
            <button onClick={() => handleInspectCandidate(c.id)} title="View Details"
              className={`${actionBtn} cursor-pointer border-[#405189]/30 bg-[#405189]/10 text-[#405189] hover:bg-[#405189] hover:text-white`}>
              <i className="fa-solid fa-eye text-[12px]"></i>
            </button>
            <button onClick={() => openNotifyModal(c)} title="Send Notification"
              className={`${actionBtn} cursor-pointer border-[#0ab39c]/30 bg-[#0ab39c]/10 text-[#0ab39c] hover:bg-[#0ab39c] hover:text-white`}>
              <i className="fa-solid fa-bell text-[12px]"></i>
            </button>
            <button onClick={() => openCommentModal(c)} title="Comment / Remarks"
              className={`${actionBtn} cursor-pointer border-amber-400/40 bg-amber-400/10 text-amber-600 hover:bg-amber-500 hover:text-white`}>
              <i className="fa-solid fa-comment-dots text-[12px]"></i>
            </button>
          </div>
        );
      },
    },
  ];

  // Name of the state chosen in the table-view filter (used for text matching).
  const selectedFilterStateName = stateFilterId
    ? (filterStateOptions.find((o) => String(o.value) === stateFilterId)?.label || '')
    : '';

  // Candidates are filtered, sorted, and paginated by the server API
  const filteredCandidates = candidates;

  const activeFilterCount =
    (statusFilter !== 'ALL' ? 1 : 0) +
    (experienceFilter !== 'ALL' ? 1 : 0) +
    (stateFilterId ? 1 : 0) +
    (cityFilters.length ? 1 : 0) +
    (sourceFilter !== 'ALL' ? 1 : 0) +
    (createdFrom || createdTo ? 1 : 0) +
    (expYearsFilter !== '' || expMonthsFilter !== '' ? 1 : 0) +
    (locationFilters.length ? 1 : 0) +
    (companyFilters.length ? 1 : 0) +
    (skillFilters.length ? 1 : 0) +
    (salaryFrom || salaryTo ? 1 : 0) +
    (designationFilters.length ? 1 : 0) +
    (jobFilter.trim() ? 1 : 0) +
    (genderFilter !== 'ALL' ? 1 : 0);

  const clearAllFilters = () => {
    setStatusFilter('ALL');
    setExperienceFilter('ALL');
    setStateFilterId('');
    setCityFilters([]);
    setFilterCityOptions([]);
    setSourceFilter('ALL');
    setCreatedFrom('');
    setCreatedTo('');
    setExpYearsFilter('');
    setExpMonthsFilter('');
    setLocationFilters([]);
    setLocationSearch('');
    setCompanyFilters([]);
    setSkillFilters([]);
    setSalaryFrom('');
    setSalaryTo('');
    setDesignationFilters([]);
    setGenderFilter('ALL');
    setJobFilter('');
  };

  // ---- Card view: the server returns exactly this page, already sorted ----
  const pagedCards = filteredCandidates;
  const cardTotalPages = Math.max(1, Math.ceil(total / pagination.pageSize));
  const safeCardPage = pagination.pageIndex + 1;
  const pageAllSelected = pagedCards.length > 0 && pagedCards.every((c: any) => selectedCardIds.includes(c.id));

  const getStatusBadgeClass = (status: string) => {
    switch (status) {
      case 'Verified':
        return 'text-emerald-700 bg-emerald-50 border-emerald-200 dark:text-emerald-400 dark:bg-emerald-950/40 dark:border-emerald-900/50';
      case 'Profile Completed':
        return 'text-indigo-700 bg-indigo-50 border-indigo-200 dark:text-indigo-400 dark:bg-indigo-950/40 dark:border-indigo-900/50';
      case 'Blocked':
        return 'text-rose-700 bg-rose-50 border-rose-200 dark:text-rose-400 dark:bg-rose-950/40 dark:border-rose-900/50';
      case 'Draft':
      default:
        return 'text-slate-600 bg-slate-100 border-slate-200 dark:text-slate-400 dark:bg-slate-800 dark:border-slate-700';
    }
  };

  if (!user) return null;
  const isStaff = user.role === 'ADMIN' || user.role === 'RECRUITER';
  const candidateUsers = usersList.filter((u: any) => u.role === 'CANDIDATE');

  return (
    <main className="flex-1 p-4 sm:p-8 overflow-y-auto w-full max-w-7xl mx-auto space-y-6">
      <BackToDashboard />

      {isFormOpen ? (
        <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none p-5 shadow-sm space-y-4">
          <div className="flex items-center justify-between border-b border-slate-100 dark:border-slate-800 pb-4">
            <h2 className="text-base font-black text-slate-800 dark:text-white flex items-center gap-2">
              {formMode === 'create' ? <><i className="fa-solid fa-user-plus mr-2 text-indigo-500"></i>Create Candidate Profile</> : <><i className="fa-solid fa-pen-to-square mr-2 text-indigo-500"></i>Edit Candidate Profile</>}
            </h2>
            <button
              onClick={() => setIsFormOpen(false)}
              className="bg-slate-50 dark:bg-slate-950 hover:bg-slate-100 dark:hover:bg-slate-800 border border-slate-200 dark:border-slate-800 rounded-none px-4 py-2 text-xs font-semibold cursor-pointer transition text-slate-700 dark:text-slate-300"
            >
              Cancel &times;
            </button>
          </div>

          {/* Profile completeness meter — updates live as fields fill (incl. after résumé parse) */}
          {(() => {
            const fd: any = formData;
            const checks: [string, boolean][] = [
              ['Résumé', !!fd.resume],
              ['Name', !!(fd.first_name && fd.last_name)],
              ['Email', !!fd.email],
              ['Phone', !!fd.phone_number],
              ['Location', !!(fd.current_location || fd.city)],
              ['Skills', !!fd.skills],
              ['Education', educations.length > 0 || !!fd.highest_qualification],
              ['Experience', !!fd.fresher || experiences.length > 0 || !!fd.current_role],
              ['Summary', !!fd.professional_summary],
            ];
            const hasFilledAny = !!(
              fd.resume ||
              fd.first_name ||
              fd.last_name ||
              fd.email ||
              fd.phone_number ||
              fd.current_location ||
              fd.city ||
              fd.skills ||
              fd.highest_qualification ||
              fd.professional_summary ||
              educations.length > 0 ||
              experiences.length > 0
            );
            const done = hasFilledAny ? checks.filter(([, v]) => v).length : 0;
            const pct = Math.round((done / checks.length) * 100);
            const barColor = pct >= 80 ? 'bg-emerald-500' : pct >= 50 ? 'bg-amber-500' : 'bg-rose-500';
            const pending = checks.filter(([, v]) => !v).map(([k]) => k);
            return (
              <div className="bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none p-3">
                <div className="flex items-center justify-between mb-1.5">
                  <span className="text-[11px] font-black uppercase tracking-wider text-slate-600 dark:text-slate-300">
                    Profile completeness
                  </span>
                  <span className={`text-sm font-black ${pct >= 80 ? 'text-emerald-600' : pct >= 50 ? 'text-amber-600' : 'text-rose-600'}`}>{pct}%</span>
                </div>
                <div className="w-full h-2 bg-slate-200 dark:bg-slate-800 rounded-none overflow-hidden">
                  <div className={`h-full ${barColor} transition-all duration-500`} style={{ width: `${pct}%` }} />
                </div>
                {pending.length > 0 && (
                  <p className="text-[10px] text-slate-400 mt-1.5">
                    Still needed: <span className="font-semibold text-slate-500 dark:text-slate-400">{pending.join(', ')}</span>
                  </p>
                )}
              </div>
            );
          })()}

          {/* Resume Upload Card */}
          <div className="bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none p-3 mb-4 space-y-2">
            <h3 className="text-xs font-black text-slate-850 dark:text-white uppercase tracking-wider flex items-center gap-2">
              <i className="fa-solid fa-file-pdf text-indigo-500 text-sm"></i>
              Upload Resume
            </h3>

            {!formData.resume ? (
              <div
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
                className={`border-2 border-dashed rounded-none p-3 text-center transition ${isDragging
                  ? 'border-indigo-600 bg-indigo-50/50 dark:bg-indigo-950/20'
                  : 'border-slate-250 hover:border-slate-350 dark:border-slate-800 dark:hover:border-slate-700'
                  }`}
              >
                <div className="flex flex-col items-center justify-center gap-1.5">
                  <div className="bg-indigo-50 dark:bg-indigo-950 p-1.5 rounded-full text-indigo-600 dark:text-indigo-400">
                    <i className="fa-solid fa-cloud-arrow-up text-base"></i>
                  </div>
                  <div>
                    <p className="text-[10px] font-bold text-slate-750 dark:text-slate-200">
                      Drag & Drop Resume
                    </p>
                    <p className="text-[8px] text-slate-400 mt-0.5">or</p>
                  </div>

                  <label className="bg-[#405189] hover:bg-[#364574] text-white px-2.5 py-1 rounded-none text-[9px] font-bold cursor-pointer transition shadow-md">
                    Browse
                    <input
                      type="file"
                      accept=".pdf"
                      onChange={handleFileChange}
                      className="hidden"
                    />
                  </label>

                  <div className="text-[8px] text-slate-400 space-y-0">
                    <p>PDF (.pdf) • Max 5 MB</p>
                  </div>
                </div>
              </div>
            ) : (
              <div className="bg-white dark:bg-slate-950 border border-slate-200 dark:border-slate-850 rounded-none p-2 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-2">
                <div className="flex items-center gap-2">
                  <div className="bg-emerald-50 dark:bg-emerald-950/40 p-1 rounded-none text-emerald-600 dark:text-emerald-455">
                    <i className="fa-solid fa-file-pdf text-sm"></i>
                  </div>
                  <div>
                    <p className="text-[8px] uppercase font-bold text-slate-400">Resume</p>
                    <p className="text-[10px] font-bold text-slate-800 dark:text-white mt-0.5">
                      {uploadedFileName || 'Resume.pdf'}
                    </p>
                    <p className="text-[8px] text-emerald-600 dark:text-emerald-450 font-bold mt-0.5 flex items-center gap-1">
                      <i className="fa-solid fa-circle-check text-xs"></i> Uploaded
                    </p>
                  </div>
                </div>

                <div className="flex flex-wrap items-center gap-1 text-[9px] w-full sm:w-auto justify-end">
                  <button
                    type="button"
                    onClick={() => setResumeView({
                      url: (formData as any).resume_url || formData.resume,
                      name: `${formData.first_name || 'Candidate'} ${formData.last_name || ''} — ${uploadedFileName || 'Resume.pdf'}`
                    })}
                    className="bg-slate-50 hover:bg-slate-100 dark:bg-slate-900 dark:hover:bg-slate-800 border border-slate-250 dark:border-slate-800 px-2 py-0.5 rounded-none font-bold cursor-pointer transition text-slate-700 dark:text-slate-300"
                  >
                    View
                  </button>
                  <label className="bg-slate-50 hover:bg-slate-100 dark:bg-slate-900 dark:hover:bg-slate-800 border border-slate-250 dark:border-slate-800 px-2 py-0.5 rounded-none font-bold cursor-pointer transition text-slate-700 dark:text-slate-300">
                    Replace
                    <input
                      type="file"
                      accept=".pdf"
                      onChange={handleFileChange}
                      className="hidden"
                    />
                  </label>
                  <button
                    type="button"
                    onClick={handleRemoveResume}
                    className="bg-rose-50 hover:bg-rose-100 dark:bg-rose-950/20 dark:hover:bg-rose-950/40 text-rose-600 dark:text-rose-450 border border-rose-200/50 dark:border-rose-900/30 px-2.5 py-1 rounded-none font-bold cursor-pointer transition"
                  >
                    Remove
                  </button>
                </div>
              </div>
            )}

            {/* Upload/Parsing Progress States */}
            {isParsing && (
              <div className="bg-indigo-50/50 dark:bg-indigo-950/20 border border-indigo-100/80 dark:border-indigo-900/40 rounded-none p-4 flex items-center gap-4 animate-pulse">
                <div className="animate-spin rounded-full h-5 w-5 border-2 border-indigo-600 border-t-transparent"></div>
                <div className="flex-1 space-y-1.5">
                  <div className="flex items-center justify-between text-xs font-bold text-indigo-650 dark:text-indigo-405">
                    <span>Parsing Resume...</span>
                    <span>{parsingProgress}%</span>
                  </div>
                  <div className="w-full bg-slate-200 dark:bg-slate-800 rounded-full h-1.5 overflow-hidden">
                    <div
                      className="bg-indigo-600 h-1.5 rounded-full transition-all duration-300"
                      style={{ width: `${parsingProgress}%` }}
                    ></div>
                  </div>
                </div>
              </div>
            )}
          </div>

          <div className="flex flex-wrap gap-1.5 border-b border-slate-100 dark:border-slate-800 pb-3">
            {[
              { id: 'personal', label: '1. Personal Info' },
              { id: 'academic', label: '2. Education & Skills' },
              { id: 'experience', label: '3. Work Experience' },
              { id: 'projects', label: '4. Projects' },
              { id: 'references', label: '5. References' },
            ].map((tab) => (
              <button
                key={tab.id}
                type="button"
                onClick={() => setActiveFormTab(tab.id as any)}
                className={`px-3 py-2 rounded-none text-xs font-bold transition cursor-pointer ${activeFormTab === tab.id ? 'bg-indigo-600 text-white shadow-md shadow-indigo-600/15' : 'bg-slate-50 hover:bg-slate-100 dark:bg-slate-950 dark:hover:bg-slate-800 text-slate-600 dark:text-slate-400'}`}
              >
                {tab.label}
              </button>
            ))}
          </div>

          {formErrorList.length > 0 && (
            <div className="rounded-none border border-rose-200 dark:border-rose-900 bg-rose-50 dark:bg-rose-950/30 p-3">
              <div className="flex items-center gap-2 mb-1.5">
                <i className="fa-solid fa-circle-exclamation text-rose-500 text-sm"></i>
                <span className="text-xs font-extrabold text-rose-700 dark:text-rose-300">
                  Please fix {formErrorList.length} issue{formErrorList.length > 1 ? 's' : ''} before saving
                </span>
              </div>
              <ul className="max-h-32 overflow-y-auto list-disc pl-8 space-y-0.5 text-[11px] text-rose-600 dark:text-rose-300/90 font-semibold">
                {formErrorList.map((msg, i) => (
                  <li key={i}>{msg}</li>
                ))}
              </ul>
            </div>
          )}

          <form onSubmit={handleSubmitCandidate} className="space-y-6 text-xs text-slate-700 dark:text-slate-300">
            <fieldset disabled={isParsing} className="space-y-6">

              {activeFormTab === 'personal' && (
                <div className="space-y-6">
                  {formMode === 'create' && (() => {
                    const filtered = jobOptions.filter((j) => j.label.toLowerCase().includes(jobPickerSearch.toLowerCase()));
                    const allChecked = filtered.length > 0 && filtered.every((j) => selectedJobIds.includes(j.value));
                    return (
                      <div className="bg-[#405189]/5 border border-[#405189]/20 rounded-none p-4">
                        <div className="flex items-center justify-between mb-2">
                          <label className="text-[10px] uppercase font-bold text-[#405189]">Assign to Job Order(s) — optional</label>
                          <span className="text-[10px] text-slate-400">{selectedJobIds.length} selected</span>
                        </div>
                        <div className="relative mb-2">
                          <i className="fa-solid fa-magnifying-glass absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-[10px]"></i>
                          <input value={jobPickerSearch} onChange={(e) => setJobPickerSearch(e.target.value)} placeholder="Search job orders..."
                            className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none pl-8 pr-3 py-2 text-xs focus:outline-none" />
                        </div>
                        <div className="border border-slate-200 dark:border-slate-800 rounded-none overflow-auto max-h-44 bg-white dark:bg-slate-900">
                          <table className="w-full text-xs">
                            <thead className="bg-slate-50 dark:bg-slate-950/40 text-slate-400 text-left text-[10px] uppercase sticky top-0">
                              <tr>
                                <th className="px-3 py-1.5 w-8">
                                  <input type="checkbox" checked={allChecked} className="accent-[#405189]"
                                    onChange={(e) => {
                                      const ids = filtered.map((j) => j.value);
                                      setSelectedJobIds((prev) => e.target.checked ? Array.from(new Set([...prev, ...ids])) : prev.filter((x) => !ids.includes(x)));
                                    }} />
                                </th>
                                <th className="px-3 py-1.5 font-semibold">Ref. #</th>
                                <th className="px-3 py-1.5 font-semibold">Title</th>
                                <th className="px-3 py-1.5 font-semibold">Company</th>
                                <th className="px-3 py-1.5 font-semibold">Status</th>
                              </tr>
                            </thead>
                            <tbody>
                              {filtered.map((j) => {
                                const checked = selectedJobIds.includes(j.value);
                                return (
                                  <tr key={j.value} className="border-t border-slate-100 dark:border-slate-800 hover:bg-slate-50 dark:hover:bg-slate-800/40 cursor-pointer"
                                    onClick={() => setSelectedJobIds((prev) => checked ? prev.filter((x) => x !== j.value) : [...prev, j.value])}>
                                    <td className="px-3 py-1.5"><input type="checkbox" checked={checked} readOnly className="accent-[#405189]" /></td>
                                    <td className="px-3 py-1.5 font-extrabold text-[#405189] dark:text-indigo-300">#{j.value}</td>
                                    <td className="px-3 py-1.5 font-bold text-slate-700 dark:text-slate-300">{j.title}</td>
                                    <td className="px-3 py-1.5 text-slate-500 dark:text-slate-400">{j.company}</td>
                                    <td className="px-3 py-1.5">
                                      <span className={`inline-flex px-2 py-0.5 rounded-none text-[10px] font-bold ${j.status === 'Published' ? 'bg-emerald-50 text-emerald-700 dark:bg-emerald-950/40 dark:text-emerald-300'
                                        : j.status === 'Closed' ? 'bg-rose-50 text-rose-700 dark:bg-rose-950/40 dark:text-rose-300'
                                          : 'bg-amber-50 text-amber-700 dark:bg-amber-950/40 dark:text-amber-300'
                                        }`}>{j.status || '—'}</span>
                                    </td>
                                  </tr>
                                );
                              })}
                              {filtered.length === 0 && <tr><td colSpan={5} className="px-3 py-4 text-center text-slate-400">No job orders.</td></tr>}
                            </tbody>
                          </table>
                        </div>
                        <span className="text-[10px] text-slate-400 mt-1 block">Candidate enters each selected job&apos;s pipeline at stage 1. Leave empty to keep them in the pool only.</span>
                      </div>
                    );
                  })()}
                  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">First Name *</label>
                      <input
                        type="text"
                        required
                        value={formData.first_name}
                        onChange={(e) => handleFirstNameChange(e.target.value)}
                        placeholder="John"
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('first_name')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Last Name *</label>
                      <input
                        type="text"
                        required
                        value={formData.last_name}
                        onChange={(e) => handleLastNameChange(e.target.value)}
                        placeholder="Doe"
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('last_name')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Phone Number *</label>
                      <PhoneInput required value={formData.phone_number} onChange={(v) => setFormData((prev: any) => ({ ...prev, phone_number: v }))} />
                      {renderError('phone_number')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Email *</label>
                      <input
                        type="email"
                        required
                        value={formData.email}
                        onChange={(e) => setFormData({ ...formData, email: e.target.value })}
                        placeholder="name@example.com"
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('email')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Alternate Phone</label>
                      <PhoneInput value={formData.alternate_phone_number} onChange={(v) => setFormData((prev: any) => ({ ...prev, alternate_phone_number: v }))} />
                      {renderError('alternate_phone_number')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Date of Birth</label>
                      <input
                        type="date"
                        value={formData.date_of_birth}
                        onChange={(e) => setFormData({ ...formData, date_of_birth: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('date_of_birth')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Gender</label>
                      <SearchableSelect
                        value={formData.gender}
                        onChange={(val) => setFormData({ ...formData, gender: val })}
                        placeholder="Select gender..."
                        options={[
                          { value: 'Male', label: 'Male' },
                          { value: 'Female', label: 'Female' },
                          { value: 'Other', label: 'Other' },
                        ]}
                      />
                      {renderError('gender')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Country</label>
                      <LocationAsyncSelect
                        locationType="country"
                        value={formData.country || ''}
                        onChange={(val, option) => {
                          const opt = Array.isArray(option) ? option[0] : option;
                          const cid = opt?.id ? Number(opt.id) : null;
                          const cname = opt?.name || (typeof val === 'string' ? val : '');
                          setSelectedCountryId(cid);
                          setSelectedStateId(null);
                          setFormData({ ...formData, country: cname, state: '', city: '' });
                        }}
                      />
                      {renderError('country')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">State</label>
                      <LocationAsyncSelect
                        locationType="state"
                        countryId={selectedCountryId}
                        value={formData.state || ''}
                        onChange={(val, option) => {
                          const opt = Array.isArray(option) ? option[0] : option;
                          const sid = opt?.id ? Number(opt.id) : null;
                          const sname = opt?.name || (typeof val === 'string' ? val : '');
                          setSelectedStateId(sid);
                          setFormData({ ...formData, state: sname, city: '' });
                        }}
                      />
                      {renderError('state')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">City</label>
                      <LocationAsyncSelect
                        locationType="city"
                        countryId={selectedCountryId}
                        stateId={selectedStateId}
                        value={formData.city || ''}
                        onChange={(val, option) => {
                          const opt = Array.isArray(option) ? option[0] : option;
                          const cname = opt?.name || (typeof val === 'string' ? val : '');
                          setFormData({ ...formData, city: cname });
                        }}
                      />
                      {renderError('city')}
                    </div>
                  </div>

                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Current Address</label>
                      <textarea
                        value={formData.current_address}
                        onChange={(e) => setFormData({ ...formData, current_address: e.target.value })}
                        rows={3}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('current_address')}
                    </div>
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Permanent Address</label>
                      <textarea
                        value={formData.permanent_address}
                        onChange={(e) => setFormData({ ...formData, permanent_address: e.target.value })}
                        rows={3}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('permanent_address')}
                    </div>
                  </div>
                </div>
              )}

              {activeFormTab === 'academic' && (
                <div className="space-y-6">
                  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Highest Qualification</label>
                      <input
                        type="text"
                        value={formData.highest_qualification}
                        onChange={(e) => setFormData({ ...formData, highest_qualification: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('highest_qualification')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">University / Board</label>
                      <input
                        type="text"
                        value={formData.university}
                        onChange={(e) => setFormData({ ...formData, university: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('university')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">College / School</label>
                      <input
                        type="text"
                        value={formData.college}
                        onChange={(e) => setFormData({ ...formData, college: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('college')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Passing Year</label>
                      <SearchableSelect
                        value={formData.passing_year ? String(formData.passing_year) : ''}
                        onChange={(val) => setFormData({ ...formData, passing_year: val || '' })}
                        placeholder="Select year..."
                        options={YEAR_OPTIONS}
                        controlBgClass="bg-white dark:bg-slate-900"
                      />
                      {renderError('passing_year')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Percentage / CGPA</label>
                      <input
                        type="text"
                        value={formData.percentage_cgpa}
                        onChange={(e) => setFormData({ ...formData, percentage_cgpa: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('percentage_cgpa')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Availability</label>
                      <SearchableSelect
                        value={formData.availability}
                        onChange={(val) => setFormData({ ...formData, availability: val })}
                        placeholder="Select availability..."
                        isClearable={false}
                        options={[
                          { value: 'Immediate', label: 'Immediate' },
                          { value: '15 Days', label: '15 Days' },
                          { value: '30 Days', label: '30 Days' },
                          { value: '60 Days', label: '60 Days' },
                          { value: '90 Days', label: '90 Days' },
                        ]}
                      />
                      {renderError('availability')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Status</label>
                      <SearchableSelect
                        value={formData.status}
                        onChange={(val) => setFormData({ ...formData, status: val })}
                        placeholder="Select status..."
                        isClearable={false}
                        options={[
                          { value: 'Draft', label: 'Draft' },
                          { value: 'Profile Completed', label: 'Profile Completed' },
                          { value: 'Verified', label: 'Verified' },
                          { value: 'Blocked', label: 'Blocked' },
                        ]}
                      />
                      {renderError('status')}
                    </div>
                  </div>

                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Key Skills</label>
                      <SearchableSelect
                        isMulti
                        isCreatable
                        options={SKILL_OPTIONS}
                        value={formData.skills ? formData.skills.split(',').map((s) => s.trim()).filter(Boolean) : []}
                        onChange={(vals: any) => {
                          const arr = (vals || []).map((v: any) => (typeof v === 'object' ? v.value : v));
                          setFormData({ ...formData, skills: arr.join(', ') });
                        }}
                        placeholder="Select or type skills..."
                        controlBgClass="bg-white dark:bg-slate-900"
                      />
                      {renderError('skills')}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Languages</label>
                      <SearchableSelect
                        isMulti
                        options={LANGUAGE_OPTIONS}
                        value={formData.languages ? formData.languages.split(',').map((l) => l.trim()).filter(Boolean) : []}
                        onChange={(vals: any) => {
                          const arr = (vals || []).map((v: any) => (typeof v === 'object' ? v.value : v));
                          setFormData({ ...formData, languages: arr.join(', ') });
                        }}
                        placeholder="Select languages..."
                        controlBgClass="bg-white dark:bg-slate-900"
                      />
                      {renderError('languages')}
                    </div>
                  </div>

                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">LinkedIn Profile URL</label>
                      <input
                        type="url"
                        value={formData.linkedin}
                        onChange={(e) => setFormData({ ...formData, linkedin: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('linkedin')}
                    </div>
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">GitHub Profile URL</label>
                      <input
                        type="url"
                        value={formData.github}
                        onChange={(e) => setFormData({ ...formData, github: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                      {renderError('github')}
                    </div>
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Portfolio URL</label>
                      <input
                        type="url"
                        value={formData.portfolio}
                        onChange={(e) => setFormData({ ...formData, portfolio: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                    </div>
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Personal Website URL</label>
                      <input
                        type="url"
                        value={formData.personal_website}
                        onChange={(e) => setFormData({ ...formData, personal_website: e.target.value })}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                    </div>
                  </div>

                  <div>
                    <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Professional Summary</label>
                    <textarea
                      value={formData.professional_summary}
                      onChange={(e) => setFormData({ ...formData, professional_summary: e.target.value })}
                      rows={4}
                      className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                    />
                    {renderError('professional_summary')}
                  </div>
                </div>
              )}

              {activeFormTab === 'experience' && (
                <div className="space-y-6">
                  <div className="bg-slate-50 dark:bg-slate-950/40 p-4 border border-slate-200 dark:border-slate-800 rounded-none">
                    <label className="flex items-center gap-2 text-xs font-bold text-slate-700 dark:text-white">
                      <input
                        type="checkbox"
                        checked={formData.fresher}
                        onChange={(e) => setFormData({ ...formData, fresher: e.target.checked })}
                        className="w-4 h-4 rounded-none text-indigo-600"
                      />
                      Is Fresher Candidate (No work experience required)
                    </label>
                  </div>

                  {!formData.fresher && (
                    <div className="space-y-6">
                      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Total Experience *</label>
                          {(() => {
                            const [expYears = '', expMonths = ''] = String(formData.total_experience ?? '').split('.');
                            const setExp = (y: string, m: string) =>
                              setFormData({
                                ...formData,
                                total_experience: y === '' && m === '' ? '' : `${y || '0'}.${m || '0'}`,
                              });
                            return (
                              <>
                                <div className="grid grid-cols-2 gap-2">
                                  <SearchableSelect
                                    value={expYears}
                                    onChange={(val) => setExp((val as string) || '', expMonths)}
                                    placeholder="Select year..."
                                    options={EXP_YEAR_OPTIONS}
                                    controlBgClass="bg-white dark:bg-slate-900"
                                  />
                                  <SearchableSelect
                                    value={expMonths}
                                    onChange={(val) => setExp(expYears, (val as string) || '')}
                                    placeholder="Select month..."
                                    options={EXP_MONTH_OPTIONS}
                                    controlBgClass="bg-white dark:bg-slate-900"
                                  />
                                </div>
                                {formData.total_experience !== '' && (
                                  <p className="text-[10px] text-slate-400 mt-1">
                                    Total experience: {formData.total_experience} ({expYears || 0} {Number(expYears || 0) === 1 ? 'year' : 'years'}, {expMonths || 0} {Number(expMonths || 0) === 1 ? 'month' : 'months'})
                                  </p>
                                )}
                              </>
                            );
                          })()}
                          {renderError('total_experience')}
                        </div>

                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Current Company</label>
                          <input
                            type="text"
                            value={formData.current_company}
                            onChange={(e) => setFormData({ ...formData, current_company: e.target.value })}
                            className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                          />
                          {renderError('current_company')}
                        </div>

                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Previous Company</label>
                          <input
                            type="text"
                            value={formData.previous_company}
                            onChange={(e) => setFormData({ ...formData, previous_company: e.target.value })}
                            className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                          />
                          {renderError('previous_company')}
                        </div>

                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Current Role *</label>
                          <SearchableSelect
                            value={formData.current_role}
                            onChange={(val) => setFormData({ ...formData, current_role: (val as string) || '' })}
                            placeholder="Select role..."
                            options={designationOptions}
                            noOptionsMessage="No designations found"
                            controlBgClass="bg-white dark:bg-slate-900"
                          />
                          {renderError('current_role')}
                        </div>

                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Employee Type</label>
                          <SearchableSelect
                            value={formData.employment_type}
                            onChange={(val) => setFormData({ ...formData, employment_type: (val as string) || '' })}
                            placeholder="Select employee type..."
                            options={[
                              { value: 'Full Time', label: 'Full Time' },
                              { value: 'Part Time', label: 'Part Time' },
                            ]}
                            controlBgClass="bg-white dark:bg-slate-900"
                          />
                          {renderError('employment_type')}
                        </div>

                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Current Location *</label>
                          <input
                            type="text"
                            value={formData.current_location}
                            onChange={(e) => setFormData({ ...formData, current_location: e.target.value })}
                            className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white"
                          />
                          {renderError('current_location')}
                        </div>

                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Preferred Cities</label>
                          <LocationAsyncSelect
                            locationType="city"
                            allowAny
                            isMulti
                            value={formData.preferred_location ? formData.preferred_location.split(',').map((s) => s.trim()).filter(Boolean) : []}
                            onChange={(vals: any) => {
                              const arr = (vals || []).map((v: any) => (typeof v === 'object' ? v.value : v));
                              setFormData({ ...formData, preferred_location: arr.join(', ') });
                            }}
                            placeholder="Select preferred cities..."
                            controlBgClass="bg-white dark:bg-slate-900"
                          />
                          {renderError('preferred_location')}
                        </div>

                        {/* Current CTC (Lakhs & Thousands dropdowns) */}
                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">
                            Current CTC {formData.current_ctc !== '' && formData.current_ctc !== null ? `(${formData.current_ctc} LPA)` : ''}
                          </label>
                          <div className="grid grid-cols-2 gap-2">
                            <div>
                              <select
                                value={parseCtcParts(formData.current_ctc).lakhs}
                                onChange={(e) => {
                                  const newLakhs = e.target.value;
                                  const currThous = parseCtcParts(formData.current_ctc).thousands;
                                  setFormData({ ...formData, current_ctc: combineCtcParts(newLakhs, currThous) });
                                }}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white cursor-pointer"
                              >
                                <option value="">Select Lakhs</option>
                                {LAKHS_OPTIONS.map((opt) => (
                                  <option key={opt.value} value={opt.value}>
                                    {opt.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                            <div>
                              <select
                                value={parseCtcParts(formData.current_ctc).thousands}
                                onChange={(e) => {
                                  const newThous = e.target.value;
                                  const currLakhs = parseCtcParts(formData.current_ctc).lakhs;
                                  setFormData({ ...formData, current_ctc: combineCtcParts(currLakhs, newThous) });
                                }}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white cursor-pointer"
                              >
                                <option value="0">00 Thousands</option>
                                {THOUSANDS_OPTIONS.map((opt) => (
                                  <option key={opt.value} value={opt.value}>
                                    {opt.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                          </div>
                          {renderError('current_ctc')}
                        </div>

                        {/* Expected CTC (Lakhs & Thousands dropdowns) */}
                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">
                            Expected CTC {formData.expected_ctc !== '' && formData.expected_ctc !== null ? `(${formData.expected_ctc} LPA)` : ''}
                          </label>
                          <div className="grid grid-cols-2 gap-2">
                            <div>
                              <select
                                value={parseCtcParts(formData.expected_ctc).lakhs}
                                onChange={(e) => {
                                  const newLakhs = e.target.value;
                                  const currThous = parseCtcParts(formData.expected_ctc).thousands;
                                  setFormData({ ...formData, expected_ctc: combineCtcParts(newLakhs, currThous) });
                                }}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white cursor-pointer"
                              >
                                <option value="">Select Lakhs</option>
                                {LAKHS_OPTIONS.map((opt) => (
                                  <option key={opt.value} value={opt.value}>
                                    {opt.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                            <div>
                              <select
                                value={parseCtcParts(formData.expected_ctc).thousands}
                                onChange={(e) => {
                                  const newThous = e.target.value;
                                  const currLakhs = parseCtcParts(formData.expected_ctc).lakhs;
                                  setFormData({ ...formData, expected_ctc: combineCtcParts(currLakhs, newThous) });
                                }}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white cursor-pointer"
                              >
                                <option value="0">00 Thousands</option>
                                {THOUSANDS_OPTIONS.map((opt) => (
                                  <option key={opt.value} value={opt.value}>
                                    {opt.label}
                                  </option>
                                ))}
                              </select>
                            </div>
                          </div>
                          {renderError('expected_ctc')}
                        </div>

                        {/* Notice Period Master Data Dropdown */}
                        <div>
                          <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Notice Period</label>
                          <select
                            value={formData.notice_period_id || (noticePeriodOptions.find((n) => String(n.value) === String(formData.notice_period))?.id ?? '')}
                            onChange={(e) => {
                              const selectedId = e.target.value;
                              const matched = noticePeriodOptions.find((n) => String(n.id) === selectedId);
                              setFormData({
                                ...formData,
                                notice_period_id: selectedId ? Number(selectedId) : '',
                                notice_period: matched ? String(matched.value) : (selectedId ? formData.notice_period : ''),
                              });
                            }}
                            className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white cursor-pointer"
                          >
                            <option value="">Select Notice Period</option>
                            {noticePeriodOptions.map((np) => (
                              <option key={np.id} value={np.id}>
                                {np.label}
                              </option>
                            ))}
                          </select>
                          {renderError('notice_period')}
                        </div>
                      </div>

                      <div className="border-t border-slate-100 dark:border-slate-800 pt-4 space-y-4">
                        <div className="flex items-center justify-between">
                          <h4 className="text-xs uppercase font-extrabold text-slate-400 tracking-wider">Detailed Work History</h4>
                          <button
                            type="button"
                            onClick={addExperience}
                            className="bg-indigo-50 hover:bg-indigo-100 text-indigo-600 dark:bg-indigo-950/40 dark:hover:bg-indigo-900/50 dark:text-indigo-400 px-3 py-1.5 rounded-none text-[11px] font-black cursor-pointer transition"
                          >
                            <i className="fa-solid fa-plus mr-1.5"></i> Add Work History
                          </button>
                        </div>

                        {experiences.length === 0 ? (
                          <p className="text-xs text-slate-400 italic py-2">No work history items added yet.</p>
                        ) : (
                          <div className="space-y-4">
                            {experiences.map((exp, idx) => (
                              <div key={idx} className="bg-slate-50 dark:bg-slate-950/40 border border-slate-200 dark:border-slate-800 rounded-none p-4 space-y-3 relative">
                                <button
                                  type="button"
                                  onClick={() => removeExperience(idx)}
                                  className="absolute top-3 right-3 text-rose-500 hover:text-rose-700 text-xs font-black cursor-pointer"
                                >
                                  Remove &times;
                                </button>
                                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
                                  <div>
                                    <label className="block text-[9px] uppercase font-bold text-slate-400">Company Name *</label>
                                    <input
                                      type="text"
                                      required
                                      value={exp.company_name}
                                      onChange={(e) => updateExperience(idx, 'company_name', e.target.value)}
                                      className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                                    />
                                  </div>
                                  <div>
                                    <label className="block text-[9px] uppercase font-bold text-slate-400">Role *</label>
                                    <input
                                      type="text"
                                      required
                                      value={exp.role}
                                      onChange={(e) => updateExperience(idx, 'role', e.target.value)}
                                      className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                                    />
                                  </div>
                                  <div>
                                    <label className="block text-[9px] uppercase font-bold text-slate-400">Joining Date *</label>
                                    <input
                                      type="date"
                                      required
                                      value={exp.joining_date}
                                      onChange={(e) => updateExperience(idx, 'joining_date', e.target.value)}
                                      className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                                    />
                                  </div>
                                  <div>
                                    <label className="block text-[9px] uppercase font-bold text-slate-400">Last Working Date</label>
                                    <input
                                      type="date"
                                      disabled={exp.is_current_company}
                                      value={exp.last_working_date || ''}
                                      onChange={(e) => updateExperience(idx, 'last_working_date', e.target.value)}
                                      className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs disabled:bg-slate-100"
                                    />
                                  </div>
                                  <div className="flex items-center pt-5">
                                    <label className="flex items-center gap-1.5 text-xs font-bold text-slate-700 dark:text-slate-300">
                                      <input
                                        type="checkbox"
                                        checked={exp.is_current_company}
                                        onChange={(e) => {
                                          updateExperience(idx, 'is_current_company', e.target.checked);
                                          if (e.target.checked) updateExperience(idx, 'last_working_date', null);
                                        }}
                                        className="w-3.5 h-3.5"
                                      />
                                      Is Current Company
                                    </label>
                                  </div>
                                </div>
                                <div>
                                  <label className="block text-[9px] uppercase font-bold text-slate-400">Responsibilities</label>
                                  <textarea
                                    value={exp.responsibilities || ''}
                                    onChange={(e) => updateExperience(idx, 'responsibilities', e.target.value)}
                                    rows={2}
                                    className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                                  />
                                </div>
                              </div>
                            ))}
                          </div>
                        )}
                      </div>
                    </div>
                  )}
                </div>
              )}

              {activeFormTab === 'projects' && (
                <div className="space-y-4">
                  <div className="flex items-center justify-between border-b border-slate-100 dark:border-slate-800 pb-2">
                    <h4 className="text-xs uppercase font-extrabold text-slate-400 tracking-wider">Candidate Projects</h4>
                    <button
                      type="button"
                      onClick={addProject}
                      className="bg-indigo-50 hover:bg-indigo-100 text-indigo-600 dark:bg-indigo-950/40 dark:hover:bg-indigo-900/50 dark:text-indigo-400 px-3 py-1.5 rounded-none text-[11px] font-black cursor-pointer transition"
                    >
                      <i className="fa-solid fa-plus mr-1.5"></i> Add Project
                    </button>
                  </div>

                  {projects.length === 0 ? (
                    <p className="text-xs text-slate-400 italic py-4 text-center">No projects added yet.</p>
                  ) : (
                    <div className="space-y-4">
                      {projects.map((proj, idx) => (
                        <div key={idx} className="bg-slate-50 dark:bg-slate-950/40 border border-slate-200 dark:border-slate-800 rounded-none p-4 space-y-3 relative">
                          <button
                            type="button"
                            onClick={() => removeProject(idx)}
                            className="absolute top-3 right-3 text-rose-500 hover:text-rose-700 text-xs font-black cursor-pointer"
                          >
                            Remove &times;
                          </button>
                          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Project Name *</label>
                              <input
                                type="text"
                                required
                                value={proj.project_name}
                                onChange={(e) => updateProject(idx, 'project_name', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Duration / Timeline</label>
                              <input
                                type="text"
                                placeholder="e.g. 3 Months, 2025"
                                value={proj.duration || ''}
                                onChange={(e) => updateProject(idx, 'duration', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Role in Project</label>
                              <input
                                type="text"
                                placeholder="e.g. Lead Developer"
                                value={proj.role || ''}
                                onChange={(e) => updateProject(idx, 'role', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                          </div>
                          <div>
                            <label className="block text-[9px] uppercase font-bold text-slate-400">Technologies Used</label>
                            <input
                              type="text"
                              placeholder="React, Node.js, SQLite (comma-separated)"
                              value={proj.technologies_used || ''}
                              onChange={(e) => updateProject(idx, 'technologies_used', e.target.value)}
                              className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                            />
                          </div>
                          <div>
                            <label className="block text-[9px] uppercase font-bold text-slate-400">Project Description</label>
                            <textarea
                              value={proj.description || ''}
                              onChange={(e) => updateProject(idx, 'description', e.target.value)}
                              rows={2}
                              className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                            />
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              )}

              {activeFormTab === 'references' && (
                <div className="space-y-4">
                  <div className="flex items-center justify-between border-b border-slate-100 dark:border-slate-800 pb-2">
                    <h4 className="text-xs uppercase font-extrabold text-slate-400 tracking-wider">Candidate References</h4>
                    <button
                      type="button"
                      onClick={addReference}
                      className="bg-indigo-50 hover:bg-indigo-100 text-indigo-600 dark:bg-indigo-950/40 dark:hover:bg-indigo-900/50 dark:text-indigo-400 px-3 py-1.5 rounded-none text-[11px] font-black cursor-pointer transition"
                    >
                      <i className="fa-solid fa-plus mr-1.5"></i> Add Reference
                    </button>
                  </div>

                  {references.length === 0 ? (
                    <p className="text-xs text-slate-400 italic py-4 text-center">No references added yet.</p>
                  ) : (
                    <div className="space-y-4">
                      {references.map((ref, idx) => (
                        <div key={idx} className="bg-slate-50 dark:bg-slate-950/40 border border-slate-200 dark:border-slate-800 rounded-none p-4 space-y-3 relative">
                          <button
                            type="button"
                            onClick={() => removeReference(idx)}
                            className="absolute top-3 right-3 text-rose-500 hover:text-rose-700 text-xs font-black cursor-pointer"
                          >
                            Remove &times;
                          </button>
                          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Name *</label>
                              <input
                                type="text"
                                required
                                value={ref.name}
                                onChange={(e) => updateReference(idx, 'name', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Company</label>
                              <input
                                type="text"
                                value={ref.company || ''}
                                onChange={(e) => updateReference(idx, 'company', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Designation</label>
                              <input
                                type="text"
                                value={ref.designation || ''}
                                onChange={(e) => updateReference(idx, 'designation', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Email Address</label>
                              <input
                                type="email"
                                value={ref.email || ''}
                                onChange={(e) => updateReference(idx, 'email', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Phone Number</label>
                              <input
                                type="text"
                                value={ref.phone || ''}
                                onChange={(e) => updateReference(idx, 'phone', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                            <div>
                              <label className="block text-[9px] uppercase font-bold text-slate-400">Relationship</label>
                              <input
                                type="text"
                                value={ref.relationship || ''}
                                onChange={(e) => updateReference(idx, 'relationship', e.target.value)}
                                className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 text-xs"
                              />
                            </div>
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              )}

              <div className="flex justify-end gap-3 border-t border-slate-100 dark:border-slate-800 pt-4">
                <button
                  type="button"
                  onClick={() => setIsFormOpen(false)}
                  className="bg-slate-50 dark:bg-slate-950 hover:bg-slate-100 dark:hover:bg-slate-800 border border-slate-200 dark:border-slate-800 rounded-none px-5 py-2.5 text-xs font-semibold transition"
                >
                  Cancel
                </button>
                <button
                  type="submit"
                  disabled={submitting}
                  className="bg-gradient-to-r from-indigo-600 to-indigo-700 hover:from-indigo-700 hover:to-indigo-800 disabled:opacity-50 text-white rounded-none px-6 py-2.5 text-xs font-extrabold shadow-md shadow-indigo-600/20 transition cursor-pointer"
                >
                  {submitting ? 'Saving Profile...' : 'Save Candidate Profile'}
                </button>
              </div>
            </fieldset>
          </form>
        </div>
      ) : (
        <div className="bg-white dark:bg-slate-900 border border-vz-border dark:border-slate-800 rounded-none shadow-sm">
          {/* Distraction-free mode (?focus=1 — e.g. the Recruiter dashboard's
              "Rejected Candidates" card): a plain title instead of the usual
              Bulk Candidate/Bulk Notification/Inactive Candidates/Add
              Candidate toolbar, so clicking in to see a specific list doesn't
              pull the user into unrelated bulk workflows. */}
          {focusMode ? (
            <div className="p-4 border-b border-vz-border dark:border-slate-800">
              <h1 className="text-base font-black text-slate-800 dark:text-white uppercase tracking-wide">
                {focusLabel || 'Candidates'}
              </h1>
            </div>
          ) : (
            <div className="relative flex flex-wrap gap-3 items-center p-4 border-b border-vz-border dark:border-slate-800">
              {isStaff && (
                <>
                  <button
                    onClick={() => { setBulkTab('excel'); setBulkModalOpen(true); }}
                    className="bg-[#0ab39c]/10 hover:bg-[#0ab39c]/20 text-[#0ab39c] border border-[#0ab39c]/30 rounded-none px-4 py-2.5 text-xs font-bold cursor-pointer transition flex items-center gap-1.5"
                  >
                    <i className="fa-solid fa-file-import"></i> Bulk Candidate
                  </button>
                  <button
                    onClick={() => setSmsModalOpen(true)}
                    className="bg-[#299cdb]/10 hover:bg-[#299cdb]/20 text-[#299cdb] border border-[#299cdb]/30 rounded-none px-4 py-2.5 text-xs font-bold cursor-pointer transition flex items-center gap-1.5"
                  >
                    <i className="fa-solid fa-bell"></i> Bulk Notification
                  </button>
                  {user.role === 'ADMIN' && (
                    <button
                      onClick={() => setDraftModalOpen(true)}
                      title="View Inactive Candidates"
                      className="ml-auto bg-slate-100 dark:bg-slate-800 hover:bg-slate-200 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 border border-slate-200 dark:border-slate-700 rounded-none px-4 py-2.5 text-xs font-bold cursor-pointer transition flex items-center gap-1.5"
                    >
                      <i className="fa-solid fa-trash-can-arrow-up"></i> Inactive Candidates
                    </button>
                  )}
                  <button
                    onClick={handleStartCreate}
                    className={`${user.role === 'ADMIN' ? '' : 'ml-auto'} bg-[#405189] hover:bg-[#364574] text-white rounded-none px-4 py-2.5 text-xs font-semibold shadow-sm cursor-pointer transition`}
                  >
                    <i className="fa-solid fa-plus mr-1.5"></i> Add Candidate
                  </button>
                </>
              )}
            </div>
          )}

          {/* Legacy-style bulk mail/SMS sender — candidate list is live data */}
          <SendSmsMailModal
            open={smsModalOpen}
            onClose={() => setSmsModalOpen(false)}
            importing={bulkUploading}
            onImportCsv={(file) => stageBulkUpload(file, 'notification')}
            csvInputRef={smsCsvInputRef}
            candidates={candidates
              // ONLY candidates from the last uploaded Excel — never the whole DB.
              // Fetched by id, so they show regardless of the current page.
              .map((c) => ({
                id: c.id,
                name: c.full_name,
                company: c.current_company ?? '',
                jobTitle: c.current_role ?? '',
                email: c.email,
                phone: c.phone_number,
                uploadedBy: user?.full_name || user?.email?.split('@')[0] || '—',
                uploadedAt: c.created_at,
              }))}
          />



          {/* View tabs: Table / Cards — with Filters + Refresh (table view only) */}
          <div className="relative flex flex-wrap items-center gap-1.5 px-4 pt-4">
            {([['table', 'Table View', 'fa-table-list'], ['cards', 'Card View', 'fa-address-card']] as const).map(([id, label, icon]) => (
              <button key={id} type="button" onClick={() => setViewMode(id)}
                className={`flex items-center gap-2 px-4 py-2 rounded-none text-xs font-bold transition cursor-pointer ${viewMode === id
                  ? 'bg-[#405189] text-white shadow-md shadow-[#405189]/15'
                  : 'bg-slate-50 hover:bg-slate-100 dark:bg-slate-950 dark:hover:bg-slate-800 text-slate-600 dark:text-slate-400'}`}>
                <i className={`fa-solid ${icon}`}></i> {label}
              </button>
            ))}

            {filterOpen && viewMode === 'table' && (
              <>
                {/* click-outside backdrop */}
                <div className="fixed inset-0 z-30" onClick={() => setFilterOpen(false)} />
                <div className="absolute left-4 right-4 top-full mt-2 z-40 bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none shadow-xl p-4 space-y-3">
                  <div className="flex items-center justify-between">
                    <span className="text-xs font-extrabold text-slate-800 dark:text-white">Filter Candidates</span>
                    {activeFilterCount > 0 && (
                      <button type="button" onClick={clearAllFilters}
                        className="text-[11px] font-bold text-rose-500 hover:text-rose-600 cursor-pointer">
                        Clear all
                      </button>
                    )}
                  </div>

                  <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Job (ID or Title)</label>
                      <input
                        type="text"
                        value={jobFilter}
                        onChange={(e) => setJobFilter(e.target.value)}
                        placeholder="e.g. #123 or Developer"
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2 text-xs focus:outline-none focus:border-[#405189] text-slate-800 dark:text-white"
                      />
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">State</label>
                      <SearchableSelect
                        value={stateFilterId}
                        onChange={(v: any) => handleFilterStateChange((v as string) || '')}
                        className="w-full"
                        placeholder="Select state…"
                        loading={filterStatesLoading}
                        options={filterStateOptions}
                        noOptionsMessage="No states found"
                        controlBgClass="bg-white dark:bg-slate-900"
                      />
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">
                        City{cityFilters.length > 0 ? ` (${cityFilters.length})` : ''}
                      </label>
                      <SearchableSelect
                        isMulti
                        wrap
                        value={cityFilters}
                        onChange={(v: any) => setCityFilters((v as string[]) || [])}
                        className="w-full"
                        placeholder={stateFilterId ? 'Select cities…' : 'Select state first'}
                        disabled={!stateFilterId}
                        loading={filterCitiesLoading}
                        options={filterCityOptions}
                        noOptionsMessage="No cities found"
                        controlBgClass="bg-white dark:bg-slate-900"
                      />
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">
                        Key Skills{skillFilters.length > 0 ? ` (${skillFilters.length})` : ''}
                      </label>
                      <SearchableSelect
                        isMulti
                        wrap
                        value={skillFilters}
                        onChange={(v: any) => setSkillFilters((v as string[]) || [])}
                        className="w-full"
                        placeholder="Select skills…"
                        loading={masterSkillsLoading}
                        options={masterSkillOptions}
                        noOptionsMessage="No skills found"
                        controlBgClass="bg-white dark:bg-slate-900"
                      />
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">
                        Company{companyFilters.length > 0 ? ` (${companyFilters.length})` : ''}
                      </label>
                      <SearchableSelect
                        isMulti
                        wrap
                        value={companyFilters}
                        onChange={(v: any) => setCompanyFilters((v as string[]) || [])}
                        className="w-full"
                        placeholder="Select companies…"
                        loading={clientsLoading}
                        options={clientOptions}
                        noOptionsMessage="No companies found"
                        controlBgClass="bg-white dark:bg-slate-900"
                      />
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Status</label>
                      <SearchableSelect
                        value={statusFilter}
                        onChange={setStatusFilter}
                        className="w-full"
                        placeholder="All Statuses"
                        isClearable={false}
                        options={[
                          { value: 'ALL', label: 'All Statuses' },
                          { value: 'Draft', label: 'Draft' },
                          { value: 'Profile Completed', label: 'Profile Completed' },
                          { value: 'Verified', label: 'Verified' },
                          { value: 'Blocked', label: 'Blocked' },
                        ]}
                      />
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Experience</label>
                      <SearchableSelect
                        value={experienceFilter}
                        onChange={setExperienceFilter}
                        className="w-full"
                        placeholder="All Experience Levels"
                        isClearable={false}
                        options={[
                          { value: 'ALL', label: 'All Experience Levels' },
                          { value: 'FRESHER', label: 'Freshers Only' },
                          { value: 'EXPERIENCED', label: 'Experienced Only' },
                        ]}
                      />
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Created From</label>
                      <input
                        type="date"
                        value={createdFrom}
                        onChange={(e) => setCreatedFrom(e.target.value)}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Created To</label>
                      <input
                        type="date"
                        value={createdTo}
                        onChange={(e) => setCreatedTo(e.target.value)}
                        className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2 text-xs focus:outline-none text-slate-800 dark:text-white"
                      />
                    </div>



                    <div className="col-span-1 sm:col-span-2">
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Salary Range</label>
                      <div className="grid grid-cols-2 gap-2">
                        <SearchableSelect
                          value={salaryFrom}
                          onChange={(v: any) => setSalaryFrom((v as string) || '')}
                          placeholder="From"
                          isCreatable={true}
                          options={SALARY_0_TO_100_OPTIONS}
                          controlBgClass="bg-white dark:bg-slate-900"
                        />
                        <SearchableSelect
                          value={salaryTo}
                          onChange={(v: any) => setSalaryTo((v as string) || '')}
                          placeholder="To"
                          isCreatable={true}
                          options={SALARY_0_TO_100_OPTIONS}
                          controlBgClass="bg-white dark:bg-slate-900"
                        />
                      </div>
                      {salaryFrom && salaryTo && Number(salaryFrom) > Number(salaryTo) && (
                        <p className="text-[10px] text-rose-500 mt-1">&quot;From&quot; salary cannot be greater than &quot;To&quot;.</p>
                      )}
                    </div>

                    <div>
                      <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Source</label>
                      <SearchableSelect
                        value={sourceFilter}
                        onChange={setSourceFilter}
                        className="w-full"
                        isClearable={false}
                        options={[
                          { value: 'ALL', label: 'All Sources' },
                          { value: 'SELF', label: 'Self Portal' },
                          { value: 'LINKEDIN', label: 'LinkedIn' },
                          { value: 'NAUKRI', label: 'Naukri' },
                          { value: 'UPLOAD', label: 'CV Upload' },
                          { value: 'REFERRAL', label: 'Referral' },
                          { value: 'WHATSAPP', label: 'WhatsApp' },
                          { value: 'SMS', label: 'SMS' },
                          { value: 'TELEGRAM', label: 'Telegram' },
                          { value: 'EMAIL', label: 'Email' },
                          { value: 'DIRECT', label: 'Direct' },
                          // Same filter value (and same API call) — only the
                          // label changes, so the word "Other" is not shown
                          // anywhere while the filter keeps working.
                          { value: 'OTHER', label: 'Not Specified' },
                        ]}
                      />
                    </div>
                  </div>

                  <div className="flex justify-end pt-1">
                    <button
                      type="button"
                      onClick={() => setFilterOpen(false)}
                      className="bg-[#405189] hover:bg-[#364574] text-white rounded-none px-6 py-2 text-xs font-bold cursor-pointer transition"
                    >
                      Done
                    </button>
                  </div>
                </div>
              </>
            )}
          </div>

          {/* Dashboard drill-down banner — list pinned to exactly the records
              behind the card that was clicked (specific ids, or a server-side
              scope: `pm_metric`/`stage_codes`, optionally narrowed by
              `owner=me`/`assigned=me`). */}
          {hasDrillDown && (
            <div className="flex items-center flex-wrap gap-2 bg-[#405189]/5 border border-[#405189]/25 rounded-none px-4 py-2.5 text-xs mb-3">
              <span className="font-bold text-[#405189] dark:text-indigo-300 flex items-center gap-1.5">
                <i className="fa-solid fa-crosshairs"></i>
                {focusLabel ? `${focusLabel}:` : 'Showing:'}
              </span>
              <span className="text-slate-600 dark:text-slate-300 font-semibold">
                {focusIds
                  ? <>{filteredCandidates.length} of {focusIds.length} record{focusIds.length === 1 ? '' : 's'} from your dashboard</>
                  : <>{total} record{total === 1 ? '' : 's'} from your dashboard</>}
              </span>
              <button
                onClick={clearDrillDown}
                className="ml-auto inline-flex items-center gap-1.5 px-2.5 py-1 bg-white dark:bg-slate-900 border border-[#405189]/30 text-[#405189] dark:text-indigo-300 font-bold hover:bg-[#405189] hover:text-white transition cursor-pointer"
              >
                <i className="fa-solid fa-xmark"></i> View All Records
              </button>
            </div>
          )}

          {viewMode === 'table' ? (
            <>
            <DataTable
              columns={columns}
              data={filteredCandidates}
              loading={loading}
              enableRowSelection
              rowSelection={rowSelection}
              onRowSelectionChange={setRowSelection}
              getRowId={(c: any) => String(c.id)}
              pageCount={Math.max(1, Math.ceil(total / pagination.pageSize))}
              controlledPagination={pagination}
              onPaginationChange={setPagination}
              controlledGlobalFilter={search}
              onGlobalFilterChange={setSearch}
              searchPlaceholder="Search by name, role, email, phone..."
              emptyStateTitle="No Candidates Found"
              emptyStateDescription="No profiles matched your filters. Try relaxing them or add a new candidate."
              renderAdditionalActions={() => (
                <>
                  <button
                    type="button"
                    onClick={() => setFilterOpen((o) => !o)}
                    className={`flex items-center gap-2 rounded-none px-4 py-2.5 text-xs font-bold cursor-pointer transition border ${activeFilterCount > 0
                      ? 'bg-[#405189]/10 text-[#405189] border-[#405189]/30'
                      : 'bg-slate-50 dark:bg-slate-950 hover:bg-slate-100 dark:hover:bg-slate-800 text-slate-750 dark:text-slate-300 border-slate-200 dark:border-slate-800'
                      }`}
                  >
                    <i className="fa-solid fa-filter"></i>
                    Filters
                    {activeFilterCount > 0 && (
                      <span className="inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded-full bg-[#405189] text-white text-[10px] font-extrabold">
                        {activeFilterCount}
                      </span>
                    )}
                    <i className={`fa-solid fa-chevron-down text-[9px] transition-transform ${filterOpen ? 'rotate-180' : ''}`}></i>
                  </button>
                  <button
                    onClick={loadCandidates}
                    title="Refresh"
                    className="w-9 h-9 flex items-center justify-center bg-slate-50 dark:bg-slate-950 hover:bg-slate-100 dark:hover:bg-slate-800 border border-slate-200 dark:border-slate-800 rounded-none text-xs cursor-pointer transition text-slate-750 dark:text-slate-300 hover:border-slate-300 dark:hover:border-slate-750"
                  >
                    <i className="fa-solid fa-rotate-right"></i>
                  </button>
                </>
              )}
            />

            {/* Selection + export bar (bottom) */}
            <div className="mt-3 flex flex-wrap items-center justify-between gap-3 bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-4 py-3">
              <span className="text-xs font-semibold text-slate-600 dark:text-slate-300">
                {Object.values(rowSelection).filter(Boolean).length > 0
                  ? `${Object.values(rowSelection).filter(Boolean).length} selected`
                  : 'Select candidates to export, or export the current page'}
              </span>
              <div className="flex items-center gap-3">
                <button
                  type="button"
                  disabled={Object.values(rowSelection).filter(Boolean).length === 0}
                  onClick={openBulkNotify}
                  className="inline-flex items-center gap-2 bg-[#405189] hover:bg-[#364574] disabled:opacity-40 text-white text-xs font-bold px-5 py-2.5 rounded-none transition cursor-pointer"
                >
                  <i className="fa-solid fa-bell"></i>
                  Notify Selected
                </button>
                <button
                  type="button"
                  onClick={exportCandidatesCsv}
                  className="inline-flex items-center gap-2 bg-[#0ab39c] hover:bg-[#099783] text-white text-xs font-bold px-5 py-2.5 rounded-none transition cursor-pointer"
                >
                  <i className="fa-solid fa-file-export"></i>
                  Export {Object.values(rowSelection).filter(Boolean).length > 0 ? 'Selected' : 'CSV'}
                </button>
              </div>
            </div>
            </>
          ) : (
            /* ---- Card View (Naukri Resdex style): left filters + right results ---- */
            <div className="p-4 grid grid-cols-1 lg:grid-cols-[260px_1fr] gap-4 items-start">
              {/* ===== Left filter sidebar ===== */}
              <aside className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none p-4 space-y-4 lg:sticky lg:top-4 lg:max-h-[calc(100vh-2rem)] lg:overflow-y-auto custom-scrollbar">
                <div className="flex items-center justify-between border-b border-slate-100 dark:border-slate-800 pb-3">
                  <span className="text-sm font-extrabold text-slate-800 dark:text-white"><i className="fa-solid fa-filter mr-2 text-[#405189]"></i>Filters</span>
                  {activeFilterCount > 0 && (
                    <button onClick={clearAllFilters} className="text-[11px] font-bold text-rose-500 hover:text-rose-600 cursor-pointer">Clear all</button>
                  )}
                </div>

                <div>
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">Keywords</label>
                  <div className="relative">
                    <i className="fa-solid fa-magnifying-glass absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-[10px]"></i>
                    <input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Name, role, skill…"
                      className="w-full bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-none pl-8 pr-3 py-2 text-xs focus:outline-none text-slate-800 dark:text-white" />
                  </div>
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">Job (ID or Title)</label>
                  <div className="relative">
                    <i className="fa-solid fa-briefcase absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-[10px]"></i>
                    <input value={jobFilter} onChange={(e) => setJobFilter(e.target.value)} placeholder="e.g. #123 or Developer"
                      className="w-full bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-none pl-8 pr-3 py-2 text-xs focus:outline-none text-slate-800 dark:text-white" />
                  </div>
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">Status</label>
                  <SearchableSelect value={statusFilter} onChange={setStatusFilter} isClearable={false}
                    options={[
                      { value: 'ALL', label: 'All Statuses' },
                      { value: 'Draft', label: 'Draft' },
                      { value: 'Profile Completed', label: 'Profile Completed' },
                      { value: 'Verified', label: 'Verified' },
                      { value: 'Blocked', label: 'Blocked' },
                    ]} />
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">Experience (Min)</label>
                  <div className="grid grid-cols-2 gap-2">
                    <SearchableSelect value={expYearsFilter} onChange={(v: any) => setExpYearsFilter((v as string) || '')}
                      placeholder="Years" options={FILTER_EXP_YEARS} />
                    <SearchableSelect value={expMonthsFilter} onChange={(v: any) => setExpMonthsFilter((v as string) || '')}
                      placeholder="Months" options={FILTER_EXP_MONTHS} />
                  </div>
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">
                    Location{locationFilters.length > 0 ? ` (${locationFilters.length})` : ''}
                  </label>
                  {jdLocationsLoading ? (
                    <p className="text-[11px] text-slate-400"><i className="fa-solid fa-spinner animate-spin mr-1.5"></i>Loading locations…</p>
                  ) : jdLocations.length === 0 ? (
                    <p className="text-[11px] text-slate-400">No JD locations found.</p>
                  ) : (
                    <>
                      {jdLocations.length > 6 && (
                        <input value={locationSearch} onChange={(e) => setLocationSearch(e.target.value)} placeholder="Search locations…"
                          className="w-full bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2 text-xs focus:outline-none text-slate-800 dark:text-white mb-2" />
                      )}
                      <div className="max-h-44 overflow-y-auto custom-scrollbar space-y-1.5 pr-1">
                        {jdLocations
                          .filter((l) => !locationSearch || l.name.toLowerCase().includes(locationSearch.toLowerCase()))
                          .map((loc) => (
                            <label key={loc.name} className="flex items-center gap-2 text-xs text-slate-600 dark:text-slate-300 cursor-pointer">
                              <input type="checkbox" checked={locationFilters.includes(loc.name)}
                                onChange={(e) => setLocationFilters((prev) => e.target.checked ? [...prev, loc.name] : prev.filter((x) => x !== loc.name))}
                                className="w-3.5 h-3.5 shrink-0 rounded-none accent-[#405189] cursor-pointer" />
                              <span className="min-w-0 break-words">{loc.name} <span className="text-slate-400">({loc.count})</span></span>
                            </label>
                          ))}
                      </div>
                    </>
                  )}
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">
                    Current Company{companyFilters.length > 0 ? ` (${companyFilters.length})` : ''}
                  </label>
                  <SearchableSelect isMulti wrap value={companyFilters} onChange={(v: any) => setCompanyFilters((v as string[]) || [])}
                    options={clientOptions} loading={clientsLoading} placeholder="Select companies…" noOptionsMessage="No companies found" />
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">
                    Key Skills{skillFilters.length > 0 ? ` (${skillFilters.length})` : ''}
                  </label>
                  <SearchableSelect isMulti wrap value={skillFilters} onChange={(v: any) => setSkillFilters((v as string[]) || [])}
                    options={masterSkillOptions} loading={masterSkillsLoading} placeholder="Select skills…" noOptionsMessage="No skills found" />
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">Salary Range</label>
                  <div className="grid grid-cols-2 gap-2">
                    <SearchableSelect
                      value={salaryFrom}
                      onChange={(v: any) => setSalaryFrom((v as string) || '')}
                      placeholder="From"
                      isCreatable={true}
                      options={SALARY_0_TO_100_OPTIONS}
                      controlBgClass="bg-slate-50 dark:bg-slate-950"
                    />
                    <SearchableSelect
                      value={salaryTo}
                      onChange={(v: any) => setSalaryTo((v as string) || '')}
                      placeholder="To"
                      isCreatable={true}
                      options={SALARY_0_TO_100_OPTIONS}
                      controlBgClass="bg-slate-50 dark:bg-slate-950"
                    />
                  </div>
                  {salaryFrom && salaryTo && Number(salaryFrom) > Number(salaryTo) && (
                    <p className="text-[10px] text-rose-500 mt-1">&quot;From&quot; salary cannot be greater than &quot;To&quot;.</p>
                  )}
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">
                    Designation{designationFilters.length > 0 ? ` (${designationFilters.length})` : ''}
                  </label>
                  <SearchableSelect isMulti wrap value={designationFilters} onChange={(v: any) => setDesignationFilters((v as string[]) || [])}
                    options={designationOptions} placeholder="Select designations…" noOptionsMessage="No designations found" />
                </div>

                <div className="border-t border-slate-100 dark:border-slate-800 pt-3">
                  <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1.5">Diversity</label>
                  <SearchableSelect value={genderFilter} onChange={(v: any) => setGenderFilter((v as string) || 'ALL')} isClearable={false}
                    options={[
                      { value: 'ALL', label: 'All Genders' },
                      { value: 'Male', label: 'Male' },
                      { value: 'Female', label: 'Female' },
                      { value: 'Other', label: 'Other' },
                    ]} />
                </div>

              </aside>

              {/* ===== Right: results ===== */}
              <div className="space-y-3 min-w-0">
                {/* Top toolbar: count + sort + show + pagination */}
                <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-4 py-2.5 flex flex-wrap items-center gap-3 text-xs">
                  <span className="font-extrabold text-slate-700 dark:text-slate-200">
                    {filteredCandidates.length} profile{filteredCandidates.length === 1 ? '' : 's'} found
                  </span>
                  {activeFilterCount > 0 && (
                    <span className="text-[10px] font-bold bg-[#405189]/10 text-[#405189] px-2 py-0.5 rounded-full">{activeFilterCount} filter{activeFilterCount > 1 ? 's' : ''} applied</span>
                  )}
                  <div className="ml-auto flex items-center gap-2">
                    <span className="text-slate-400 font-semibold">Sort by:</span>
                    <select value={cardSort} onChange={(e) => { setCardSort(e.target.value as any); }}
                      className="border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 rounded-none px-2 py-1.5 text-xs font-semibold text-slate-700 dark:text-slate-300 focus:outline-none cursor-pointer">
                      <option value="newest">Newest</option>
                      <option value="name">Name (A-Z)</option>
                      <option value="experience">Experience</option>
                    </select>
                    <span className="text-slate-400 font-semibold ml-2">Show</span>
                    <select value={pagination.pageSize} onChange={(e) => { const ps = Number(e.target.value); setPagination((p) => ({ pageIndex: 0, pageSize: ps })); }}
                      className="border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900 rounded-none px-2 py-1.5 text-xs font-semibold text-slate-700 dark:text-slate-300 focus:outline-none cursor-pointer">
                      {[10, 20, 40].map((n) => <option key={n} value={n}>{n}</option>)}
                    </select>
                    <div className="flex items-center gap-1 ml-2">
                      <button disabled={safeCardPage <= 1} onClick={() => setPagination((p) => ({ ...p, pageIndex: Math.max(0, p.pageIndex - 1) }))}
                        className="w-7 h-7 rounded-none border border-slate-200 dark:border-slate-800 text-slate-500 disabled:opacity-40 hover:bg-slate-50 dark:hover:bg-slate-800 cursor-pointer transition">
                        <i className="fa-solid fa-chevron-left text-[10px]"></i>
                      </button>
                      <span className="border border-slate-200 dark:border-slate-800 rounded-none px-2.5 py-1.5 font-semibold text-slate-600 dark:text-slate-300 whitespace-nowrap">
                        Page {safeCardPage} of {cardTotalPages}
                      </span>
                      <button disabled={safeCardPage >= cardTotalPages} onClick={() => setPagination((p) => ({ ...p, pageIndex: Math.min(cardTotalPages - 1, p.pageIndex + 1) }))}
                        className="w-7 h-7 rounded-none border border-slate-200 dark:border-slate-800 text-slate-500 disabled:opacity-40 hover:bg-slate-50 dark:hover:bg-slate-800 cursor-pointer transition">
                        <i className="fa-solid fa-chevron-right text-[10px]"></i>
                      </button>
                    </div>
                  </div>
                </div>

                {/* Selection bar: select all + bulk mail */}
                <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-4 py-2.5 flex flex-wrap items-center gap-4 text-xs">
                  <label className="flex items-center gap-2 font-semibold text-slate-600 dark:text-slate-300 cursor-pointer">
                    <input type="checkbox" checked={pageAllSelected}
                      onChange={(e) => {
                        const ids = pagedCards.map((c: any) => c.id);
                        setSelectedCardIds((prev) => e.target.checked ? Array.from(new Set([...prev, ...ids])) : prev.filter((x) => !ids.includes(x)));
                      }}
                      className="w-4 h-4 rounded-none accent-[#405189] cursor-pointer" />
                    Select all
                  </label>
                  {selectedCardIds.length > 0 && (
                    <span className="text-[#405189] font-bold">{selectedCardIds.length} selected</span>
                  )}
                  <div className="ml-auto flex items-center gap-3">
                    <span className="text-slate-400 font-semibold hidden sm:inline">Reach selected candidates:</span>
                    <button
                      disabled={selectedCardIds.length === 0}
                      onClick={openBulkNotify}
                      className="bg-[#405189] hover:bg-[#364574] disabled:opacity-40 text-white rounded-none px-4 py-1.5 text-xs font-bold cursor-pointer transition">
                      <i className="fa-solid fa-bell mr-1.5"></i>Notify
                    </button>
                  </div>
                </div>

                {pagedCards.length === 0 ? (
                  <div className="py-16 text-center text-slate-400 text-sm bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none">No profiles matched your filters.</div>
                ) : pagedCards.map((cd: any) => {
                  const hl = (text: string) => {
                    const q = (skillFilters[0] || search || '').trim();
                    if (!q || !text.toLowerCase().includes(q.toLowerCase())) return <>{text}</>;
                    const i = text.toLowerCase().indexOf(q.toLowerCase());
                    return (<>{text.slice(0, i)}<span className="bg-amber-100 dark:bg-amber-950/50 rounded-none px-0.5">{text.slice(i, i + q.length)}</span>{text.slice(i + q.length)}</>);
                  };
                  return (
                    <div key={cd.id} className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none hover:shadow-md hover:border-[#405189]/30 transition overflow-hidden">
                      <div className="flex flex-col md:flex-row">
                        {/* ===== Left: main info ===== */}
                        <div className="flex-1 min-w-0 p-5">
                          <div className="flex items-center gap-2.5">
                            <input type="checkbox" checked={selectedCardIds.includes(cd.id)}
                              onChange={(e) => setSelectedCardIds((prev) => e.target.checked ? [...prev, cd.id] : prev.filter((x) => x !== cd.id))}
                              className="w-4 h-4 shrink-0 rounded-none accent-[#405189] cursor-pointer" />
                            <button onClick={() => router.push(`/candidates/${cd.id}`)}
                              className="min-w-0 text-left break-words text-[15px] font-extrabold text-slate-800 dark:text-white hover:text-[#405189] hover:underline cursor-pointer">{cd.full_name}</button>
                          </div>

                          <div className="flex flex-wrap items-center gap-x-4 gap-y-1 mt-1.5 text-[11px] text-slate-500 dark:text-slate-400 font-semibold">
                            <span><i className="fa-solid fa-briefcase mr-1.5 text-slate-400"></i>{cd.fresher ? 'Fresher' : `${cd.total_experience ?? '—'} yrs`}</span>
                            {cd.current_ctc != null && <span><i className="fa-solid fa-indian-rupee-sign mr-1 text-slate-400"></i>{cd.current_ctc} Lacs</span>}
                            <span><i className="fa-solid fa-location-dot mr-1.5 text-slate-400"></i>{cd.city || '—'}{cd.state ? `, ${cd.state}` : ''}</span>
                          </div>

                          <div className="grid grid-cols-[110px_minmax(0,1fr)] gap-x-3 gap-y-2 mt-3.5 text-xs">
                            <span className="text-[#405189]/70 dark:text-indigo-300/70 font-semibold">Current</span>
                            <span className="min-w-0 break-words text-slate-800 dark:text-slate-200 font-semibold">
                              {cd.current_role ? hl(cd.current_role) : '—'}{cd.current_company ? <span className="font-normal"> at {cd.current_company}</span> : null}
                            </span>
                            {cd.previous_company && (<>
                              <span className="text-[#405189]/70 dark:text-indigo-300/70 font-semibold">Previous</span>
                              <span className="min-w-0 break-words text-slate-700 dark:text-slate-300">{cd.previous_company}</span>
                            </>)}
                            {cd.highest_qualification && (<>
                              <span className="text-[#405189]/70 dark:text-indigo-300/70 font-semibold">Education</span>
                              <span className="min-w-0 break-words text-slate-700 dark:text-slate-300">
                                {cd.highest_qualification}{cd.university ? ` — ${cd.university}` : ''}{cd.passing_year ? `, ${cd.passing_year}` : ''}
                              </span>
                            </>)}
                            {cd.preferred_location && (<>
                              <span className="text-[#405189]/70 dark:text-indigo-300/70 font-semibold">Pref. locations</span>
                              <span className="min-w-0 break-words text-slate-700 dark:text-slate-300">{cd.preferred_location}</span>
                            </>)}
                            <span className="text-[#405189]/70 dark:text-indigo-300/70 font-semibold">Key skills</span>
                            <span className="min-w-0 flex flex-wrap items-center gap-x-1.5 gap-y-1 text-slate-700 dark:text-slate-300 leading-relaxed">
                              {(cd.skills || []).length ? (cd.skills || []).map((s: string, i: number) => (
                                <span key={s} className="inline-flex items-center font-semibold break-words max-w-full">
                                  {hl(s)}{i < cd.skills.length - 1 && <span className="text-slate-300 dark:text-slate-600 font-normal ml-1.5">|</span>}
                                </span>
                              )) : '—'}
                            </span>
                          </div>
                        </div>

                        {/* ===== Right: avatar + contact actions (divided) ===== */}
                        <div className="md:w-56 shrink-0 border-t md:border-t-0 md:border-l border-slate-100 dark:border-slate-800 p-5 flex flex-col items-center text-center gap-2.5">
                          <div className="w-16 h-16 rounded-full bg-[#405189]/10 text-[#405189] flex items-center justify-center text-xl font-extrabold">
                            {(cd.full_name || 'C').charAt(0).toUpperCase()}
                          </div>
                          {(cd.current_role || cd.current_company) && (
                            <p className="text-[11px] text-slate-500 dark:text-slate-400 leading-snug">
                              {cd.current_role ? hl(cd.current_role) : ''}{cd.current_company ? ` at ${cd.current_company}` : ''}
                            </p>
                          )}
                          <button
                            onClick={() => revealPhone(cd)}
                            disabled={revealing}
                            className="w-full border border-[#405189]/40 text-[#405189] hover:bg-[#405189]/5 rounded-none px-3 py-2 text-[11px] font-bold cursor-pointer transition disabled:opacity-50">
                            {revealedPhoneId === cd.id ? revealedPhone : (revealing ? 'Loading…' : 'View phone number')}
                          </button>
                          <button onClick={() => openNotifyModal(cd)}
                            className="w-full border border-[#405189]/40 text-[#405189] hover:bg-[#405189]/5 rounded-none px-3 py-2 text-[11px] font-bold cursor-pointer transition">
                            <i className="fa-solid fa-bell mr-1.5"></i>Notify candidate
                          </button>
                          <p className="text-[10px] text-slate-400">{cd.email ? 'Email & phone on record' : 'Phone on record'}</p>
                          <div className="mt-auto flex items-center gap-3 text-[11px] font-bold text-[#405189]">
                            <button onClick={() => router.push(`/candidates/${cd.id}`)} className="hover:underline cursor-pointer">Profile</button>
                            <span className="text-slate-300 dark:text-slate-700">|</span>
                            <button onClick={() => handleInspectCandidate(cd.id)} className="hover:underline cursor-pointer">Quick view</button>
                            <span className="text-slate-300 dark:text-slate-700">|</span>
                            <button onClick={() => openCommentModal(cd)} className="hover:underline cursor-pointer text-amber-600">
                              <i className="fa-solid fa-comment-dots mr-1"></i>Comment
                            </button>
                          </div>
                        </div>
                      </div>

                      {/* ===== Card footer ===== */}
                      <div className="flex flex-wrap items-center justify-end gap-4 px-5 py-2 border-t border-slate-100 dark:border-slate-800 bg-slate-50/60 dark:bg-slate-950/40 text-[10px] text-slate-400 font-semibold">
                        {cd.resume ? (
                          <button onClick={() => setResumeView({ url: cd.resume_url || cd.resume, name: `${cd.full_name} — Resume` })}
                            className="text-[#405189] hover:underline cursor-pointer font-bold" title="Preview Resume">
                            <i className="fa-solid fa-paperclip mr-1"></i>CV
                          </button>
                        ) : (
                          <button disabled title="No resume uploaded"
                            className="text-slate-300 dark:text-slate-600 opacity-60 cursor-not-allowed font-bold">
                            <i className="fa-solid fa-paperclip mr-1"></i>CV
                          </button>
                        )}
                        <span>Added {formatDate(cd.created_at)}</span>
                        {cd.updated_at && <span>Modified {formatDate(cd.updated_at)}</span>}
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          )}
        </div>
      )}

      {/* Bulk mail to selected card-view candidates */}
      {/* Bulk Notify — full Notify modal (templates, channels, CC, history)
          pre-loaded with the candidates selected in either view. */}
      <NotifyCandidateModal
        open={bulkNotifyList !== null}
        onClose={() => setBulkNotifyList(null)}
        candidates={bulkNotifyList ?? []}
      />

      {bulkMailOpen && (
        <div className="fixed inset-0 z-[65] flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-slate-950/60 backdrop-blur-sm" onClick={() => !bulkMailSending && setBulkMailOpen(false)} />
          <div className="relative z-10 w-full max-w-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none shadow-2xl p-6">
            <div className="flex items-center justify-between mb-4">
              <h3 className="text-lg font-bold text-slate-900 dark:text-white">
                Send Mail — {selectedCardIds.length} candidate{selectedCardIds.length === 1 ? '' : 's'}
              </h3>
              <button onClick={() => !bulkMailSending && setBulkMailOpen(false)}
                className="w-8 h-8 rounded-none flex items-center justify-center text-slate-400 hover:text-slate-700 hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
                <i className="fa-solid fa-xmark"></i>
              </button>
            </div>
            <div className="space-y-3">
              <div>
                <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Subject</label>
                <input value={bulkMailSubject} onChange={(e) => setBulkMailSubject(e.target.value)}
                  className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white" />
              </div>
              <div>
                <label className="block text-[10px] uppercase font-bold text-slate-400 mb-1">Message <span className="normal-case font-semibold">— use {'{name}'} for the candidate&apos;s name</span></label>
                <textarea value={bulkMailBody} onChange={(e) => setBulkMailBody(e.target.value)} rows={7}
                  className="w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none px-3 py-2.5 text-xs focus:outline-none text-slate-800 dark:text-white font-sans" />
              </div>
              <div className="flex justify-end gap-3">
                <button onClick={() => setBulkMailOpen(false)}
                  className="bg-slate-50 dark:bg-slate-950 hover:bg-slate-100 dark:hover:bg-slate-800 border border-slate-200 dark:border-slate-800 rounded-none px-5 py-2.5 text-xs font-semibold transition cursor-pointer">
                  Cancel
                </button>
                <button disabled={bulkMailSending} onClick={sendBulkMailToSelected}
                  className="bg-[#405189] hover:bg-[#364574] disabled:opacity-50 text-white rounded-none px-6 py-2.5 text-xs font-extrabold shadow-md transition cursor-pointer">
                  {bulkMailSending ? (<><i className="fa-solid fa-spinner fa-spin mr-1.5"></i>Sending…</>) : (<><i className="fa-solid fa-paper-plane mr-1.5"></i>Send Mail</>)}
                </button>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Comment / Remarks history modal */}
      {commentCandidate && (
        <div className="fixed inset-0 z-[60] flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-slate-950/60 backdrop-blur-sm" onClick={() => setCommentCandidate(null)} />
          <div className="relative z-10 w-full max-w-3xl bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 shadow-2xl p-6 max-h-[85vh] flex flex-col">
            <div className="flex items-center justify-between mb-4 shrink-0">
              <div>
                <h3 className="text-lg font-bold text-slate-900 dark:text-white">
                  <i className="fa-solid fa-comment-dots text-amber-500 mr-2"></i>Comment History
                </h3>
                <p className="text-xs text-slate-400 mt-0.5">{commentCandidate.full_name} · {commentCandidate.phone_number || 'no phone'}</p>
              </div>
              <button onClick={() => setCommentCandidate(null)}
                className="w-8 h-8 flex items-center justify-center text-slate-400 hover:text-slate-700 hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
                <i className="fa-solid fa-xmark"></i>
              </button>
            </div>

            {/* Add remark */}
            <div className="flex gap-2 shrink-0 mb-4">
              <input
                value={commentText}
                onChange={(e) => setCommentText(e.target.value)}
                onKeyDown={(e) => { if (e.key === 'Enter') addCommentFromList(); }}
                placeholder='e.g. "Called candidate — connected, interested. Will revert by Friday."'
                className="flex-1 bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 px-3 py-2.5 text-xs focus:outline-none focus:border-[#405189] text-slate-800 dark:text-white"
              />
              <button disabled={commentAdding || !commentText.trim()} onClick={addCommentFromList}
                className="bg-[#405189] hover:bg-[#364574] text-white text-xs font-bold px-4 py-2.5 disabled:opacity-50 cursor-pointer whitespace-nowrap">
                {commentAdding ? 'Adding…' : 'Add Remark'}
              </button>
            </div>

            {/* History table with search */}
            <div className="overflow-y-auto flex-1 min-h-0">
              {commentLoading ? (
                <p className="text-xs text-slate-400 py-8 text-center"><i className="fa-solid fa-spinner fa-spin mr-2"></i>Loading history…</p>
              ) : commentList.length === 0 ? (
                <p className="text-xs text-slate-400 py-8 text-center">No remarks yet. Record call outcomes here.</p>
              ) : (() => {
                const q = commentSearch.trim().toLowerCase();
                const visible = commentList.filter((cm) =>
                  !q ||
                  cm.comment.toLowerCase().includes(q) ||
                  (cm.by || '').toLowerCase().includes(q) ||
                  formatDateTime(cm.created_at).toLowerCase().includes(q)
                );
                return (
                  <>
                    <div className="relative mb-2">
                      <i className="fa-solid fa-magnifying-glass absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-[10px]"></i>
                      <input
                        value={commentSearch}
                        onChange={(e) => setCommentSearch(e.target.value)}
                        placeholder="Search remarks, added by, date…"
                        className="w-full max-w-xs bg-slate-50 dark:bg-slate-950 border border-slate-200 dark:border-slate-800 pl-8 pr-3 py-2 text-xs focus:outline-none focus:border-[#405189] text-slate-800 dark:text-white"
                      />
                      <span className="ml-3 text-[10px] text-slate-400 font-semibold">{visible.length} of {commentList.length} remark{commentList.length === 1 ? '' : 's'}</span>
                    </div>
                    <div className="border border-slate-200 dark:border-slate-800 overflow-hidden">
                      <table className="w-full text-xs">
                        <thead className="bg-slate-50 dark:bg-slate-950/40 text-slate-400 text-left text-[10px] uppercase sticky top-0">
                          <tr>
                            <th className="px-3 py-2 font-semibold w-12">S.No.</th>
                            <th className="px-3 py-2 font-semibold">Comment / Remark</th>
                            <th className="px-3 py-2 font-semibold whitespace-nowrap">Added By</th>
                            <th className="px-3 py-2 font-semibold whitespace-nowrap">Date &amp; Time</th>
                          </tr>
                        </thead>
                        <tbody>
                          {visible.length === 0 ? (
                            <tr><td colSpan={4} className="px-3 py-6 text-center text-slate-400">No remarks match your search.</td></tr>
                          ) : visible.map((cm, i) => (
                            <tr key={cm.id} className="border-t border-slate-100 dark:border-slate-800 align-top hover:bg-slate-50 dark:hover:bg-slate-800/40">
                              <td className="px-3 py-2.5 text-slate-400 font-semibold">{i + 1}</td>
                              <td className="px-3 py-2.5 text-slate-700 dark:text-slate-300">{cm.comment}</td>
                              <td className="px-3 py-2.5 font-semibold text-slate-600 dark:text-slate-300 whitespace-nowrap">{cm.by || '—'}</td>
                              <td className="px-3 py-2.5 text-slate-400 whitespace-nowrap">{formatDateTime(cm.created_at)}</td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    </div>
                  </>
                );
              })()}
            </div>
          </div>
        </div>
      )}

      <NotifyCandidateModal
        open={notifyCandidate !== null}
        onClose={() => setNotifyCandidate(null)}
        candidates={notifyCandidate ? [notifyCandidate] : []}
      />

      {bulkModalOpen && (
        <div className="fixed inset-0 z-[60] flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-slate-950/60 backdrop-blur-sm" onClick={() => !bulkUploading && setBulkModalOpen(false)} />
          <div className="relative z-10 w-full max-w-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-none shadow-2xl p-6">
            <div className="flex items-center justify-between mb-4">
              <h3 className="text-lg font-bold text-slate-900 dark:text-white">Bulk Candidate Import</h3>
              <button onClick={() => !bulkUploading && setBulkModalOpen(false)}
                className="w-8 h-8 rounded-none flex items-center justify-center text-slate-400 hover:text-slate-700 hover:bg-slate-100 dark:hover:bg-slate-800 transition cursor-pointer">
                <i className="fa-solid fa-xmark"></i>
              </button>
            </div>

            {/* Two upload methods, one tab each */}
            <div className="flex gap-1 mb-4">
              {([
                { key: 'excel', label: 'Upload Excel/CSV', icon: 'fa-solid fa-file-excel' },
                { key: 'resumes', label: 'Upload Resumes', icon: 'fa-solid fa-file-lines' },
              ] as const).map((t) => (
                <button key={t.key} type="button" onClick={() => !bulkUploading && setBulkTab(t.key)}
                  className={`flex-1 flex items-center justify-center gap-1.5 px-2 sm:px-4 py-2.5 text-xs font-bold transition cursor-pointer ${bulkTab === t.key
                    ? 'bg-[#405189] text-white'
                    : 'bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-200 dark:hover:bg-slate-700'
                    }`}>
                  <i className={`${t.icon} text-[11px]`} />
                  <span className="truncate">{t.label}</span>
                </button>
              ))}
            </div>

            {bulkTab === 'excel' ? (
              <>
                {/* Sample format download — on top */}
                <div className="flex flex-wrap items-center justify-between gap-3 rounded-none border border-[#405189]/20 bg-[#405189]/5 px-4 py-3 mb-4">
                  <div className="min-w-0">
                    <p className="text-xs font-extrabold text-[#405189]">Bulk Candidate Format</p>
                    <p className="text-[11px] text-slate-500 dark:text-slate-400 mt-0.5">Download the Excel template, fill it, then upload below.</p>
                  </div>
                  <a href="/templates/candidate-bulk-template.xlsx" download
                    className="shrink-0 inline-flex items-center gap-1.5 px-3 py-2 rounded-none text-xs font-bold text-white bg-[#405189] hover:bg-[#364574] transition">
                    <i className="fa-solid fa-download"></i> Download
                  </a>
                </div>

                {/* Upload dropzone */}
                <div
                  onDragOver={(e) => { e.preventDefault(); setBulkDragOver(true); }}
                  onDragLeave={() => setBulkDragOver(false)}
                  onDrop={(e) => { e.preventDefault(); setBulkDragOver(false); const f = e.dataTransfer.files?.[0]; if (f && !bulkUploading) stageBulkUpload(f); }}
                  className={`rounded-none border-2 border-dashed px-4 py-8 text-center transition ${bulkDragOver ? 'border-[#0ab39c] bg-[#0ab39c]/5' : 'border-slate-300 dark:border-slate-700 bg-slate-50 dark:bg-slate-950'}`}
                >
                  {bulkUploading ? (
                    <p className="text-sm text-[#0ab39c] font-semibold"><i className="fa-solid fa-spinner fa-spin mr-2"></i>Importing candidates…</p>
                  ) : (
                    <label className="cursor-pointer block">
                      <i className="fa-solid fa-cloud-arrow-up text-3xl text-slate-400"></i>
                      <p className="text-sm font-semibold text-slate-700 dark:text-slate-200 mt-2">Drag &amp; drop your file here, or <span className="text-[#0ab39c]">browse</span></p>
                      <p className="text-xs text-slate-400 mt-1">Excel (.xlsx) or CSV — duplicate email/contact rows are skipped</p>
                      <input type="file" accept=".csv,.xlsx" className="hidden" ref={bulkFileInputRef}
                        onChange={(e) => { const f = e.target.files?.[0]; if (f) stageBulkUpload(f, 'bulk_candidate'); e.currentTarget.value = ''; }} />
                    </label>
                  )}
                </div>

                <p className="text-[11px] text-slate-400 mt-3">
                  Tip: put one or more <b>Joborder ID</b>s (e.g. <code>20,21</code>) in the first column to add the candidate directly into those job pipelines.
                </p>
              </>
            ) : (
              <>
                {/* SRC-004: bulk multi-CV upload */}
                <div
                  className="rounded-none border-2 border-dashed border-slate-300 dark:border-slate-700 bg-slate-50 dark:bg-slate-950 px-4 py-8 text-center transition"
                  onDragOver={(e) => e.preventDefault()}
                  onDrop={(e) => { e.preventDefault(); if (!bulkUploading && e.dataTransfer.files?.length) handleBulkCVUpload(e.dataTransfer.files); }}
                >
                  {bulkUploading ? (
                    <p className="text-sm text-[#0ab39c] font-semibold"><i className="fa-solid fa-spinner fa-spin mr-2"></i>Parsing CVs…</p>
                  ) : (
                    <label className="cursor-pointer block">
                      <i className="fa-solid fa-file-arrow-up text-3xl text-slate-400"></i>
                      <p className="text-sm font-semibold text-slate-700 dark:text-slate-200 mt-2">Drag &amp; drop multiple CVs, or <span className="text-[#0ab39c]">browse</span></p>
                      <p className="text-xs text-slate-400 mt-1">PDF / DOCX — each CV is parsed into a candidate (duplicates skipped)</p>
                      <input type="file" accept=".pdf,.docx" multiple className="hidden"
                        onChange={(e) => { if (e.target.files?.length) handleBulkCVUpload(e.target.files); e.currentTarget.value = ''; }} />
                    </label>
                  )}
                </div>

                <p className="text-[11px] text-slate-400 mt-3">
                  Each resume is parsed automatically — name, contact and other details are extracted into a new candidate profile.
                </p>
              </>
            )}
          </div>
        </div>
      )}

      {/* Preview + confirm the picked bulk file before it is uploaded */}
      {pendingBulkFile && (
        <BulkUploadPreviewModal
          file={pendingBulkFile}
          busy={bulkUploading}
          onConfirm={async (uploadFile) => {
            await handleBulkUpload(uploadFile); // original file, or a rebuilt .xlsx of only the selected rows
            setPendingBulkFile(null);
          }}
          onCancel={() => {
            setPendingBulkFile(null);
            // "Choose Another File" reopens the SAME picker this file came
            // from, instead of just closing back to a modal the user then has
            // to click "Choose file" on again themselves. Called synchronously
            // (not via setTimeout) so browsers still treat opening the native
            // file dialog as part of this same click — some browsers refuse
            // to show it otherwise.
            (pendingBulkSource === 'notification' ? smsCsvInputRef : bulkFileInputRef).current?.click();
          }}
        />
      )}

      {resumeView && (
        <ResumePreviewModal
          url={resumeView.url}
          name={resumeView.name}
          onClose={() => setResumeView(null)}
        />
      )}

      {user.role === 'ADMIN' && (
        <DeletedCandidatesModal open={draftModalOpen} onClose={() => setDraftModalOpen(false)} />
      )}

      {selectedCandidate && (
        <div className="fixed inset-0 z-50 flex items-center justify-end">
          <div
            className="absolute inset-0 bg-slate-950/60 backdrop-blur-sm"
            onClick={() => setSelectedCandidate(null)}
          />

          <div className="relative w-full max-w-2xl h-screen bg-white dark:bg-slate-900 border-l border-slate-200 dark:border-slate-800 shadow-2xl flex flex-col p-6 overflow-y-auto animate-in slide-in-from-right duration-350 z-10 space-y-6">

            <div className="flex items-center justify-between border-b border-slate-100 dark:border-slate-800 pb-4">
              <h3 className="text-base font-black text-slate-800 dark:text-white flex items-center gap-2">
                🔎 Candidate Details
              </h3>
              <button
                onClick={() => setSelectedCandidate(null)}
                className="p-1 rounded-none hover:bg-slate-100 dark:hover:bg-slate-800 text-slate-500 cursor-pointer"
              >
                <X className="w-5 h-5" />
              </button>
            </div>

            {isStaff && (
              <div className="flex gap-3 border-b border-slate-100 dark:border-slate-800 pb-4">
                <button
                  onClick={handleStartEdit}
                  className="flex-1 bg-gradient-to-r from-indigo-600 to-indigo-700 hover:from-indigo-700 hover:to-indigo-800 text-white py-2.5 rounded-none text-xs font-extrabold shadow-md shadow-indigo-600/20 transition cursor-pointer text-center"
                >
                  <i className="fa-solid fa-pen-to-square mr-2"></i> Edit Profile
                </button>
                <button
                  onClick={() => handleDeleteCandidate(selectedCandidate.id)}
                  className="flex-1 bg-rose-50 hover:bg-rose-100 text-rose-600 dark:bg-rose-950/30 dark:hover:bg-rose-900/50 dark:border-rose-900/40 dark:text-rose-400 py-2.5 rounded-none text-xs font-extrabold border border-rose-200 dark:border-rose-900/40 transition cursor-pointer text-center"
                >
                  <i className="fa-solid fa-trash mr-2"></i> Delete Profile
                </button>
              </div>
            )}

            <div className="space-y-6">
              <div className="flex gap-4 items-center">
                <div className="w-16 h-16 rounded-none bg-indigo-100 dark:bg-indigo-950/60 flex items-center justify-center text-2xl font-black text-indigo-600 dark:text-indigo-400">
                  {selectedCandidate.first_name?.[0]}{selectedCandidate.last_name?.[0]}
                </div>
                <div>
                  <h4 className="text-xl font-black text-slate-900 dark:text-white">
                    {selectedCandidate.first_name} {selectedCandidate.last_name}
                  </h4>
                  <p className="text-xs text-slate-500 dark:text-slate-400 flex items-center gap-1 mt-1 font-semibold">
                    <MapPin className="w-3.5 h-3.5" />
                    {selectedCandidate.city}, {selectedCandidate.state}, {selectedCandidate.country}
                  </p>
                </div>
              </div>

              {selectedCandidate.professional_summary && (
                <div className="p-4 bg-slate-50 dark:bg-slate-950/40 rounded-none border border-slate-200 dark:border-slate-800">
                  <p className="text-xs uppercase tracking-wider font-extrabold text-slate-400 mb-2">Professional Summary</p>
                  <p className="text-xs leading-relaxed text-slate-600 dark:text-slate-300">{selectedCandidate.professional_summary}</p>
                </div>
              )}

              <div className="grid grid-cols-2 gap-4">
                <div>
                  <p className="text-[10px] uppercase font-bold text-slate-400">Email Address</p>
                  <p className="text-xs font-bold text-slate-800 dark:text-white mt-1">{selectedCandidate.email}</p>
                </div>
                <div>
                  <p className="text-[10px] uppercase font-bold text-slate-400">Phone Number</p>
                  <p className="text-xs font-bold text-slate-800 dark:text-white mt-1">{selectedCandidate.phone_number}</p>
                </div>
                <div>
                  <p className="text-[10px] uppercase font-bold text-slate-400">Gender / Date of Birth</p>
                  <p className="text-xs font-bold text-slate-800 dark:text-white mt-1">
                    {selectedCandidate.gender || 'N/A'} • {selectedCandidate.date_of_birth || 'N/A'}
                  </p>
                </div>
                <div>
                  <p className="text-[10px] uppercase font-bold text-slate-400">Availability / Source</p>
                  <p className="text-xs font-bold text-slate-800 dark:text-white mt-1">
                    {selectedCandidate.availability || 'Immediate'} • ({sourceLabel(selectedCandidate.source)})
                  </p>
                </div>
              </div>

              {selectedCandidate.experiences?.length > 0 && (
                <div>
                  <h5 className="text-xs uppercase font-extrabold text-slate-400 mb-3 tracking-wider">Work Experience</h5>
                  <div className="space-y-3">
                    {selectedCandidate.experiences.map((exp: any) => (
                      <div key={exp.id} className="border-l-2 border-indigo-500 pl-4 py-1">
                        <p className="text-sm font-bold text-slate-900 dark:text-white">{exp.role}</p>
                        <p className="text-xs text-slate-500 dark:text-slate-400">{exp.company_name} • {exp.joining_date} to {exp.is_current_company ? 'Present' : exp.last_working_date}</p>
                        {exp.responsibilities && <p className="text-[11px] text-slate-400 mt-1">{exp.responsibilities}</p>}
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {selectedCandidate.educations?.length > 0 && (
                <div>
                  <h5 className="text-xs uppercase font-extrabold text-slate-400 mb-3 tracking-wider">Education</h5>
                  <div className="space-y-3">
                    {selectedCandidate.educations.map((edu: any) => (
                      <div key={edu.id} className="border-l-2 border-emerald-500 pl-4 py-1">
                        <p className="text-sm font-bold text-slate-900 dark:text-white">{edu.degree_name}</p>
                        <p className="text-xs text-slate-500 dark:text-slate-400">{edu.institution_name} • Class of {edu.passing_year}</p>
                        <p className="text-[10px] text-emerald-600 dark:text-emerald-400 mt-0.5">CGPA/Percentage: {edu.percentage_cgpa}</p>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {selectedCandidate.projects?.length > 0 && (
                <div>
                  <h5 className="text-xs uppercase font-extrabold text-slate-400 mb-3 tracking-wider">Projects</h5>
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                    {selectedCandidate.projects.map((proj: any) => (
                      <div key={proj.id} className="p-3.5 bg-slate-50 dark:bg-slate-950/40 border border-slate-200 dark:border-slate-800 rounded-none">
                        <p className="text-xs font-bold text-slate-900 dark:text-white">{proj.project_name}</p>
                        <p className="text-[10px] text-slate-400 mt-1">{proj.description}</p>
                        <p className="text-[9px] font-mono text-indigo-600 dark:text-indigo-400 mt-2">Tech: {proj.technologies_used}</p>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {selectedCandidate.documents?.length > 0 && (
                <div>
                  <h5 className="text-xs uppercase font-extrabold text-slate-400 mb-3 tracking-wider">Verification Documents</h5>
                  <div className="space-y-2">
                    {selectedCandidate.documents.map((doc: any) => (
                      <div key={doc.id} className="flex justify-between items-center p-3 border border-slate-200 dark:border-slate-800 rounded-none bg-slate-50/50 dark:bg-slate-950/20">
                        <div>
                          <p className="text-xs font-bold text-slate-900 dark:text-white">{doc.document_type}</p>
                          <p className="text-[10px] text-slate-400 mt-0.5">Verification status: <span className="font-extrabold">{doc.verification_status}</span></p>
                        </div>
                        <a
                          href={doc.file}
                          target="_blank"
                          rel="noreferrer"
                          className="text-xs font-bold text-indigo-600 dark:text-indigo-400 hover:underline"
                        >
                          <span className="flex items-center gap-1.5"><i className="fa-solid fa-download"></i> Download File</span>
                        </a>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>
      )}

    </main>
  );
}
