import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";

import {
  Box,
  Button,
  Checkbox,
  Chip,
  FormControl,
  FormControlLabel,
  IconButton,
  InputAdornment,
  InputLabel,
  Menu,
  MenuItem,
  Paper,
  Select,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TablePagination,
  TableRow,
  TableSortLabel,
  TextField,
  Tooltip,
  Typography,
} from "@mui/material";
import useMediaQuery from "@mui/material/useMediaQuery";
import { alpha, useTheme } from "@mui/material/styles";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
import RestoreFromTrashOutlinedIcon from "@mui/icons-material/RestoreFromTrashOutlined";
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
import ViewColumnIcon from "@mui/icons-material/ViewColumn";
import SearchIcon from "@mui/icons-material/Search";
import WorkOutlineIcon from "@mui/icons-material/WorkOutline";

import { api } from "../api";
import ViewStateNotice from "./ViewStateNotice";
import { useCompanies } from "../hooks/useCompanies";
import { useDebouncedValue } from "../hooks/useDebouncedValue";
import { formatSalary } from "../salary";
import { statusLabel, statusTone } from "../pipeline";
import EditJobDialog from "./EditJobDialog";
import { useToast } from "../toast";
import SavedViewsMenu, { SavedViewParams } from "./SavedViewsMenu";
import { useDialogActions } from "../dialogs";
import { useI18n } from "../i18n/I18nProvider";
import { JobApplication } from "../types";
import { useViewResource } from "../hooks/useViewResource";
import { getWorkflowAction } from "../jobWorkflowSignals";

interface PagedResult<T> {
  items: T[];
  total: number;
  page: number;
  pageSize: number;
}

type RowActionSignal = {
  label: string;
  detail: string;
  onClick: () => void;
  variant: "contained" | "outlined";
  color: "warning" | "primary";
};

type JobRowViewModel = {
  job: JobApplication;
  toneName: string;
  tags: string[];
  actionSignals: RowActionSignal[];
  appliedDateLabel: string;
  isSelected: boolean;
};

export type JobTableColumns = {
  status: boolean;
  dateApplied: boolean;
  daysSince: boolean;
  jobUrl: boolean;
};

interface Props {
  refreshToken: number;
  pageSize: 15 | 20 | 25;
  onPageSizeChange: (n: 15 | 20 | 25) => void;
  columns: JobTableColumns;
  onColumnsChange: (next: JobTableColumns) => void;
  mode?: "jobs" | "trash";
}

type JobSortKey = "dateApplied" | "company" | "jobTitle" | "status" | "daysSince" | "location";
type ReadinessFilter = "all" | "needs-work" | "interview";

const JOB_SORT_KEYS: JobSortKey[] = ["dateApplied", "company", "jobTitle", "status", "daysSince", "location"];
const JOB_STATUS_FILTERS = ["Applied", "Waiting", "Interview", "Offer", "Rejected", "Ghosted"];

function queryPage(search: string): number {
  const value = Number(new URLSearchParams(search).get("page"));
  return Number.isInteger(value) && value > 1 ? value - 1 : 0;
}

function queryCompany(search: string): number | "All" {
  const value = Number(new URLSearchParams(search).get("companyId"));
  return Number.isInteger(value) && value > 0 ? value : "All";
}

function queryStatus(search: string): string {
  const value = new URLSearchParams(search).get("status");
  return value && JOB_STATUS_FILTERS.includes(value) ? value : "All";
}

function queryReadiness(search: string): ReadinessFilter {
  const value = new URLSearchParams(search).get("readiness");
  return value === "needs-work" || value === "interview" ? value : "all";
}

function querySort(search: string): JobSortKey {
  const value = new URLSearchParams(search).get("sortBy") as JobSortKey | null;
  return value && JOB_SORT_KEYS.includes(value) ? value : "dateApplied";
}

function parseTags(raw?: string | null): string[] {
  if (!raw) return [];
  try {
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? parsed.filter((x) => typeof x === "string") : [];
  } catch {
    return raw.split(/[,;\n]/).map((x) => x.trim()).filter(Boolean);
  }
}


function EmptyJobsState({ firstTime, onOpenSettings, t }: { firstTime: boolean; onOpenSettings: () => void; t: (key: any) => string }) {
  if (!firstTime) {
    return <Typography sx={{ py: 2, textAlign: "center", color: "text.secondary" }}>{t("jobTableNoJobsFound")}</Typography>;
  }
  return (
    <Box sx={{ py: 5, textAlign: "center" }}>
      <Box
        sx={{
          width: 56,
          height: 56,
          mx: "auto",
          mb: 2,
          borderRadius: 3,
          display: "grid",
          placeItems: "center",
          bgcolor: (theme) => alpha(theme.palette.primary.main, 0.12),
          color: "primary.main",
        }}
      >
        <WorkOutlineIcon fontSize="medium" />
      </Box>
      <Typography sx={{ fontWeight: 800, mb: 0.5 }}>{t("jobTableEmptyFirstTimeTitle")}</Typography>
      <Typography sx={{ color: "text.secondary", mb: 1.5, maxWidth: 440, mx: "auto" }}>{t("jobTableEmptyFirstTimeBody")}</Typography>
      <Button variant="text" onClick={onOpenSettings}>{t("jobTableEmptyFirstTimeBookmarklet")}</Button>
    </Box>
  );
}

function isInteractiveTarget(target: EventTarget | null): boolean {
  return target instanceof Element && Boolean(target.closest("button, a, input, select, textarea, [role='button'], [role='menuitem'], [role='checkbox']"));
}

export default function JobTable({ refreshToken, pageSize, onPageSizeChange, columns, onColumnsChange, mode = "jobs" }: Props) {
  const theme = useTheme();
  const isMobile = useMediaQuery("(max-width:767.95px)");
  const { toast } = useToast();
  const { t } = useI18n();
  const { confirmAction } = useDialogActions();
  const location = useLocation();
  const navigate = useNavigate();
  const listRouteRef = useRef(`${location.pathname}${location.search}`);
  const restoredFocusJobIdRef = useRef<number | null>(null);
  const [jobs, setJobs] = useState<JobApplication[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(() => queryPage(location.search));
  const [selectedIds, setSelectedIds] = useState<number[]>([]);
  const [search, setSearch] = useState(() => new URLSearchParams(location.search).get("q") ?? "");
  const debouncedSearch = useDebouncedValue(search, 250);
  const [includeDeleted, setIncludeDeleted] = useState(() => mode === "trash" || new URLSearchParams(location.search).get("includeDeleted") === "1");
  const [columnsAnchor, setColumnsAnchor] = useState<null | HTMLElement>(null);
  const [statusFilter, setStatusFilter] = useState(() => queryStatus(location.search));
  const [locationFilter, setLocationFilter] = useState(() => new URLSearchParams(location.search).get("location") ?? "");
  const debouncedLocation = useDebouncedValue(locationFilter, 250);
  const [needsFollowUpOnly, setNeedsFollowUpOnly] = useState(() => new URLSearchParams(location.search).get("needsFollowUp") === "1");
  const [readinessFilter, setReadinessFilter] = useState<ReadinessFilter>(() => queryReadiness(location.search));
  const { companies, error: companiesError, reload: reloadCompanies } = useCompanies();
  const [companyFilterId, setCompanyFilterId] = useState<number | "All">(() => queryCompany(location.search));
  const [editJobId, setEditJobId] = useState<number | null>(null);
  const [reloadToken, setReloadToken] = useState(0);
  const [statusAnchor, setStatusAnchor] = useState<null | HTMLElement>(null);
  const [statusJobId, setStatusJobId] = useState<number | null>(null);
  const [sortBy, setSortBy] = useState<JobSortKey>(() => querySort(location.search));
  const [sortDir, setSortDir] = useState<"asc" | "desc">(() => new URLSearchParams(location.search).get("sortDir") === "asc" ? "asc" : "desc");

  const updateListRoute = useCallback((updates: Record<string, string | null>) => {
    const next = new URLSearchParams(location.search);
    Object.entries(updates).forEach(([key, value]) => {
      if (value) next.set(key, value);
      else next.delete(key);
    });
    const search = next.toString() ? `?${next.toString()}` : "";
    listRouteRef.current = `${location.pathname}${search}`;
    navigate({ pathname: location.pathname, search }, { replace: true, state: location.state });
  }, [location.pathname, location.search, location.state, navigate]);

  useEffect(() => {
    listRouteRef.current = `${location.pathname}${location.search}`;
  }, [location.pathname, location.search]);

  useEffect(() => {
    const next = new URLSearchParams(location.search);
    setSearch(next.get("q") ?? "");
    setStatusFilter(queryStatus(location.search));
    setCompanyFilterId(queryCompany(location.search));
    setLocationFilter(next.get("location") ?? "");
    setNeedsFollowUpOnly(next.get("needsFollowUp") === "1");
    setReadinessFilter(queryReadiness(location.search));
    setIncludeDeleted(mode === "trash" || next.get("includeDeleted") === "1");
    setSortBy(querySort(location.search));
    setSortDir(next.get("sortDir") === "asc" ? "asc" : "desc");
    setPage(queryPage(location.search));
  }, [location.search, mode]);

  const changeSearch = (value: string) => {
    setSearch(value);
    setPage(0);
    updateListRoute({ q: value || null, page: null });
  };

  const changeStatus = (value: string) => {
    setStatusFilter(value);
    setPage(0);
    updateListRoute({ status: value === "All" ? null : value, page: null });
  };

  const changeCompany = (value: number | "All") => {
    setCompanyFilterId(value);
    setPage(0);
    updateListRoute({ companyId: value === "All" ? null : String(value), page: null });
  };

  const changeLocation = (value: string) => {
    setLocationFilter(value);
    setPage(0);
    updateListRoute({ location: value || null, page: null });
  };

  const changeNeedsFollowUp = (value: boolean) => {
    setNeedsFollowUpOnly(value);
    setPage(0);
    updateListRoute({ needsFollowUp: value ? "1" : null, page: null });
  };

  const changeReadiness = (value: ReadinessFilter) => {
    setReadinessFilter(value);
    setPage(0);
    updateListRoute({ readiness: value === "all" ? null : value, page: null });
  };

  const changeIncludeDeleted = (value: boolean) => {
    setIncludeDeleted(value);
    setPage(0);
    updateListRoute({ includeDeleted: value && mode !== "trash" ? "1" : null, page: null });
  };

  const applySavedView = (view: SavedViewParams) => {
    const nextCompany = view.companyId ?? "All";
    setSearch(view.q ?? "");
    setStatusFilter(view.status ?? "All");
    setCompanyFilterId(nextCompany);
    setLocationFilter(view.location ?? "");
    setNeedsFollowUpOnly(Boolean(view.needsFollowUp));
    setReadinessFilter(view.readiness ?? "all");
    setPage(0);
    updateListRoute({
      q: view.q || null,
      status: view.status || null,
      companyId: nextCompany === "All" ? null : String(nextCompany),
      location: view.location || null,
      needsFollowUp: view.needsFollowUp ? "1" : null,
      readiness: view.readiness ?? null,
      page: null,
    });
  };

  const openJob = useCallback((jobId: number, path?: string) => {
    navigate(path ?? `/jobs/${jobId}`, { state: { from: listRouteRef.current, focusJobId: jobId } });
  }, [navigate]);

  const params = useMemo(() => ({
    page: page + 1,
    pageSize,
    q: debouncedSearch.trim() || undefined,
    status: statusFilter !== "All" ? statusFilter : undefined,
    companyId: companyFilterId === "All" ? undefined : companyFilterId,
    location: debouncedLocation.trim() || undefined,
    includeDeleted,
    deletedOnly: mode === "trash" ? true : undefined,
    sortBy,
    sortDir,
    needsFollowUp: needsFollowUpOnly ? true : undefined,
    readiness: readinessFilter === "all" ? undefined : readinessFilter,
  }), [page, pageSize, debouncedSearch, statusFilter, companyFilterId, debouncedLocation, includeDeleted, mode, sortBy, sortDir, needsFollowUpOnly, readinessFilter]);

  const jobsResource = useViewResource(
    async () => {
      const r = await api.get<PagedResult<JobApplication>>("/jobapplications", { params });
      return r.data;
    },
    {
      initialData: { items: [], total: 0, page: 1, pageSize },
      errorMessage: t("jobTableJobsLoadFailed"),
      deps: [params, refreshToken, reloadToken, pageSize, t],
    },
  );

  useEffect(() => {
    setJobs(jobsResource.data.items);
    setTotal(jobsResource.data.total);
    if (!jobsResource.error) {
      setSelectedIds([]);
    }
  }, [jobsResource.data, jobsResource.error]);

  const requestSort = (key: JobSortKey) => {
    const nextDirection = sortBy === key ? (sortDir === "asc" ? "desc" : "asc") : "asc";
    setSortBy(key);
    setSortDir(nextDirection);
    setPage(0);
    updateListRoute({ sortBy: key === "dateApplied" ? null : key, sortDir: key === "dateApplied" && nextDirection === "desc" ? null : nextDirection, page: null });
  };

  const filteredJobs = jobs;

  useEffect(() => {
    const focusJobId = (location.state as { focusJobId?: unknown } | null)?.focusJobId;
    if (typeof focusJobId !== "number" || restoredFocusJobIdRef.current === focusJobId || jobsResource.loading) return;
    const row = document.querySelector<HTMLElement>(`[data-job-row-id="${focusJobId}"]`);
    if (!row) return;
    restoredFocusJobIdRef.current = focusJobId;
    row.focus();
  }, [filteredJobs, jobsResource.loading, location.state]);

  // Distinguishes "you have zero jobs, period" from "no results match your filters" so the
  // empty state can actually help a first-time user instead of just saying "nothing here".
  const noFiltersActive = !debouncedSearch.trim() && statusFilter === "All" && companyFilterId === "All"
    && !debouncedLocation.trim() && !needsFollowUpOnly && readinessFilter === "all";
  const isFirstTimeEmpty = mode === "jobs" && total === 0 && noFiltersActive;

  const selectedIdSet = useMemo(() => new Set(selectedIds), [selectedIds]);

  const selectedAllOnPage = filteredJobs.length > 0 && filteredJobs.every((job) => selectedIdSet.has(job.id));

  const toggleSelectAll = (checked: boolean) => {
    setSelectedIds(checked ? filteredJobs.map((job) => job.id) : []);
  };

  const toggleSelected = (id: number, checked: boolean) => {
    setSelectedIds((prev) => checked ? [...prev, id] : prev.filter((x) => x !== id));
  };

  const confirmDelete = async (jobsToDelete: JobApplication[]) => {
    if (jobsToDelete.length === 0) return false;
    if (jobsToDelete.length === 1) {
      const job = jobsToDelete[0];
      return confirmAction(t("jobTableMoveOneConfirm", { title: job.jobTitle, company: job.company?.name ?? t("jobTableCompany") }), { title: t("jobTableMoveToTrashTitle"), confirmLabel: t("jobTableMove"), destructive: true });
    }
    return confirmAction(t("jobTableMoveManyConfirm", { count: jobsToDelete.length }), { title: t("jobTableMoveJobsToTrashTitle"), confirmLabel: t("jobTableMove"), destructive: true });
  };

  const softDelete = async (job: JobApplication) => {
    if (!(await confirmDelete([job]))) return;
    try {
      await api.delete(`/jobapplications/${job.id}`);
      toast(t("jobTableMovedToTrash"), "success", { label: "Undo", onClick: () => { void restore(job.id); } });
      setReloadToken((token) => token + 1);
    } catch {
      toast(t("jobTableDeleteFailed"), "error");
    }
  };

  const restore = async (id: number) => {
    try {
      await api.post(`/jobapplications/${id}/restore`);
      toast(t("jobTableRestored"), "success");
      setReloadToken((token) => token + 1);
    } catch {
      toast(t("jobTableRestoreFailed"), "error");
    }
  };

  const setStatusQuick = async (id: number, status: string) => {
    try {
      await api.patch(`/jobapplications/${id}/status`, { status });
      toast(t("jobTableStatusSet", { status }), "success");
      setReloadToken((token) => token + 1);
    } catch {
      toast(t("jobTableStatusUpdateFailed"), "error");
    }
  };

  const runBulkAction = async (action: "delete" | "restore" | "status", value?: string) => {
    if (selectedIds.length === 0) return;
    const selectedJobs = jobs.filter((job) => selectedIdSet.has(job.id));
    if (action === "delete" && !(await confirmDelete(selectedJobs))) return;
    try {
      await Promise.all(selectedIds.map((id) => {
        if (action === "delete") return api.delete(`/jobapplications/${id}`);
        if (action === "restore") return api.post(`/jobapplications/${id}/restore`);
        return api.patch(`/jobapplications/${id}/status`, { status: value });
      }));
      toast(t("jobTableUpdatedJobs", { count: selectedIds.length }), "success");
      setReloadToken((token) => token + 1);
      setSelectedIds([]);
    } catch {
      toast(t("jobTableBulkActionFailed"), "error");
    }
  };

  const buildWorkflowActionSignal = useCallback((job: JobApplication): RowActionSignal | null => {
    const action = getWorkflowAction(job, {
      packageWork: t("jobTablePackageWork"),
      followUp: t("jobTableFollowUp"),
      interviewPrep: t("jobTableInterviewStage"),
      readiness: t("jobTableReadiness"),
    });
    if (!action || job.isDeleted) return null;

    return {
      label: action.label,
      detail: action.detail,
      onClick: () => openJob(job.id, action.path),
      variant: action.key === "follow-up" ? "contained" : "outlined",
      color: action.key === "follow-up" ? "warning" : "primary",
    };
  }, [openJob, t]);

  const rowModels = useMemo<JobRowViewModel[]>(() => filteredJobs.map((job) => {
    const actionSignal = buildWorkflowActionSignal(job);
    return {
      job,
      toneName: statusTone(job.status),
      tags: parseTags(job.tags),
      actionSignals: actionSignal ? [actionSignal] : [],
      appliedDateLabel: job.dateApplied ? new Date(job.dateApplied).toLocaleDateString() : "—",
      isSelected: selectedIdSet.has(job.id),
    };
  }), [buildWorkflowActionSignal, filteredJobs, selectedIdSet]);

  const statusOptions = ["Waiting", "Interview", "Offer", "Rejected", "Ghosted"] as const;
  const visibleDesktopColumns = 6 + Number(columns.status) + Number(columns.dateApplied) + Number(columns.daysSince) + Number(columns.jobUrl);
  const selectedCompanyIsLoading = companyFilterId !== "All" && !companies.some((company) => company.id === companyFilterId);

  return (
    <Box>
      {isMobile ? (
        <Paper sx={{ mt: 2, p: 1.25, borderRadius: 4 }}>
          <Stack spacing={1.1}>
            <TextField
              label={t("jobTableSearch")}
              value={search}
              onChange={(e) => changeSearch(e.target.value)}
              placeholder={t("jobTableSearchPlaceholder")}
              size="small"
              InputProps={{ startAdornment: <InputAdornment position="start"><SearchIcon fontSize="small" /></InputAdornment> }}
              fullWidth
            />

            <Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 1 }}>
              <FormControl fullWidth size="small">
                <InputLabel id="job-table-status-label">{t("jobTableStatus")}</InputLabel>
                <Select labelId="job-table-status-label" value={statusFilter} label={t("jobTableStatus")} onChange={(e) => changeStatus(e.target.value)}>
                  {[t("jobTableAll"), t("statusApplied"), t("statusWaiting"), t("statusInterview"), t("statusOffer"), t("statusRejected"), t("statusGhosted")].map((s) => <MenuItem key={s} value={s === t("jobTableAll") ? "All" : s === t("statusApplied") ? "Applied" : s === t("statusWaiting") ? "Waiting" : s === t("statusInterview") ? "Interview" : s === t("statusOffer") ? "Offer" : s === t("statusRejected") ? "Rejected" : "Ghosted"}>{s}</MenuItem>)}
                </Select>
              </FormControl>

              <FormControl fullWidth size="small">
                <InputLabel id="job-table-company-label">{t("jobTableCompany")}</InputLabel>
                <Select labelId="job-table-company-label" value={companyFilterId} label={t("jobTableCompany")} onChange={(e) => changeCompany(e.target.value as number | "All")}>
                  <MenuItem value="All">{t("jobTableAll")}</MenuItem>
                  {selectedCompanyIsLoading ? <MenuItem value={companyFilterId}>Company {companyFilterId}</MenuItem> : null}
                  {companies.map((c) => <MenuItem key={c.id} value={c.id}>{c.name}</MenuItem>)}
                </Select>
              </FormControl>
            </Box>

            <Box sx={{ display: "grid", gridTemplateColumns: mode === "jobs" ? "1fr 1fr" : "1fr", gap: 1 }}>
              <TextField
                label={t("jobTableLocation")}
                value={locationFilter}
                onChange={(e) => changeLocation(e.target.value)}
                fullWidth
              />

              {mode === "jobs" ? (
                <FormControl fullWidth size="small">
                  <InputLabel id="job-table-readiness-label">{t("jobTableReadiness")}</InputLabel>
                  <Select labelId="job-table-readiness-label" value={readinessFilter} label={t("jobTableReadiness")} onChange={(e) => changeReadiness(e.target.value as ReadinessFilter)}>
                    <MenuItem value="all">{t("jobTableAllReadiness")}</MenuItem>
                    <MenuItem value="needs-work">{t("jobTableNeedsWork")}</MenuItem>
                    <MenuItem value="interview">{t("jobTableInterviewStage")}</MenuItem>
                  </Select>
                </FormControl>
              ) : null}
            </Box>

            {mode === "jobs" ? (
              <Box
                sx={{
                  display: "grid",
                  gridTemplateColumns: "1fr 1fr",
                  gap: 0.25,
                  px: 0.25,
                  py: 0.5,
                  borderRadius: 3,
                  backgroundColor: alpha(theme.palette.primary.main, 0.03),
                  border: "1px solid",
                  borderColor: alpha(theme.palette.primary.main, 0.1),
                }}
              >
                <FormControlLabel control={<Checkbox checked={needsFollowUpOnly} onChange={(e) => changeNeedsFollowUp(e.target.checked)} />} label={t("jobTableNeedsFollowUp")} sx={{ mr: 0, ml: -0.5 }} />
                <FormControlLabel control={<Checkbox checked={includeDeleted} onChange={(e) => changeIncludeDeleted(e.target.checked)} />} label={t("jobTableShowDeleted")} sx={{ mr: 0, ml: -0.5 }} />
              </Box>
            ) : null}

            <Box sx={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) auto", gap: 0.75, alignItems: "center", pt: 0.25 }}>
              <Box sx={{ minWidth: 0 }}>
                <SavedViewsMenu current={{ q: search.trim() || undefined, status: statusFilter !== "All" ? statusFilter : undefined, companyId: companyFilterId === "All" ? undefined : (companyFilterId as number), location: locationFilter.trim() || undefined, needsFollowUp: needsFollowUpOnly ? true : undefined, readiness: readinessFilter === "all" ? undefined : readinessFilter }} onApply={applySavedView} />
              </Box>
              <Button variant="text" size="small" startIcon={<ViewColumnIcon />} onClick={(e) => setColumnsAnchor(e.currentTarget)} sx={{ justifySelf: "end", minHeight: 40, px: 1 }}>
                {t("jobTableColumns")}
              </Button>
            </Box>
          </Stack>
        </Paper>
      ) : (
        <Box sx={{ display: "flex", gap: 2, alignItems: "center", justifyContent: "space-between", mt: 2, flexWrap: "wrap" }}>
          <TextField
            label={t("jobTableSearch")}
            value={search}
            onChange={(e) => changeSearch(e.target.value)}
            placeholder={t("jobTableSearchPlaceholder")}
            size="small"
            InputProps={{ startAdornment: <InputAdornment position="start"><SearchIcon fontSize="small" /></InputAdornment> }}
            sx={{ width: { xs: "100%", md: "auto" }, minWidth: { xs: 0, md: 320 }, flex: { xs: "1 1 100%", md: "1 1 320px" } }}
          />

          <FormControl sx={{ width: { xs: "100%", sm: 180 } }} size="small">
            <InputLabel id="job-table-status-label">{t("jobTableStatus")}</InputLabel>
            <Select labelId="job-table-status-label" value={statusFilter} label={t("jobTableStatus")} onChange={(e) => changeStatus(e.target.value)}>
              {[t("jobTableAll"), t("statusApplied"), t("statusWaiting"), t("statusInterview"), t("statusOffer"), t("statusRejected"), t("statusGhosted")].map((s) => <MenuItem key={s} value={s === t("jobTableAll") ? "All" : s === t("statusApplied") ? "Applied" : s === t("statusWaiting") ? "Waiting" : s === t("statusInterview") ? "Interview" : s === t("statusOffer") ? "Offer" : s === t("statusRejected") ? "Rejected" : "Ghosted"}>{s}</MenuItem>)}
            </Select>
          </FormControl>

          <FormControl sx={{ width: { xs: "100%", sm: 220 } }} size="small">
            <InputLabel id="job-table-company-label">{t("jobTableCompany")}</InputLabel>
            <Select labelId="job-table-company-label" value={companyFilterId} label={t("jobTableCompany")} onChange={(e) => changeCompany(e.target.value as number | "All")}>
              <MenuItem value="All">{t("jobTableAll")}</MenuItem>
              {selectedCompanyIsLoading ? <MenuItem value={companyFilterId}>Company {companyFilterId}</MenuItem> : null}
              {companies.map((c) => <MenuItem key={c.id} value={c.id}>{c.name}</MenuItem>)}
            </Select>
          </FormControl>

          <TextField
            label={t("jobTableLocation")}
            value={locationFilter}
            onChange={(e) => changeLocation(e.target.value)}
            sx={{ width: { xs: "100%", sm: 220 }, flex: { xs: "1 1 100%", md: "1 1 200px" } }}
          />

          <Box sx={{ display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap", width: { xs: "100%", xl: "auto" } }}>
            {mode === "jobs" ? <FormControlLabel control={<Checkbox checked={needsFollowUpOnly} onChange={(e) => changeNeedsFollowUp(e.target.checked)} />} label={t("jobTableNeedsFollowUp")} sx={{ mr: 0 }} /> : null}
            {mode === "jobs" ? (
              <FormControl size="small" sx={{ width: { xs: "100%", sm: 180 } }}>
                <InputLabel id="job-table-readiness-label">{t("jobTableReadiness")}</InputLabel>
                <Select labelId="job-table-readiness-label" value={readinessFilter} label={t("jobTableReadiness")} onChange={(e) => changeReadiness(e.target.value as ReadinessFilter)}>
                  <MenuItem value="all">{t("jobTableAllReadiness")}</MenuItem>
                  <MenuItem value="needs-work">{t("jobTableNeedsWork")}</MenuItem>
                  <MenuItem value="interview">{t("jobTableInterviewStage")}</MenuItem>
                </Select>
              </FormControl>
            ) : null}
            {mode === "jobs" ? <FormControlLabel control={<Checkbox checked={includeDeleted} onChange={(e) => changeIncludeDeleted(e.target.checked)} />} label={t("jobTableShowDeleted")} sx={{ mr: 0 }} /> : null}
            <SavedViewsMenu current={{ q: search.trim() || undefined, status: statusFilter !== "All" ? statusFilter : undefined, companyId: companyFilterId === "All" ? undefined : (companyFilterId as number), location: locationFilter.trim() || undefined, needsFollowUp: needsFollowUpOnly ? true : undefined, readiness: readinessFilter === "all" ? undefined : readinessFilter }} onApply={applySavedView} />
            {!isMobile ? <Tooltip title={t("jobTableColumns")}><IconButton aria-label={t("jobTableColumns")} onClick={(e) => setColumnsAnchor(e.currentTarget)}><ViewColumnIcon /></IconButton></Tooltip> : null}
          </Box>
        </Box>
      )}

      {selectedIds.length > 0 ? (
        <Paper sx={{ mt: 2, p: 1.5, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, flexWrap: "wrap" }}>
          <Typography sx={{ fontWeight: 800 }}>{t("jobTableSelected", { count: selectedIds.length })}</Typography>
          <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", width: { xs: "100%", sm: "auto" } }}>
            {mode === "trash" ? <Button variant="outlined" onClick={() => void runBulkAction("restore")} sx={{ width: { xs: "100%", sm: "auto" } }}>{t("jobTableRestoreSelected")}</Button> : <Button variant="outlined" color="error" onClick={() => void runBulkAction("delete")} sx={{ width: { xs: "100%", sm: "auto" } }}>{t("jobTableDeleteSelected")}</Button>}
            {mode === "jobs" ? statusOptions.map((status) => <Button key={status} variant="outlined" onClick={() => void runBulkAction("status", status)} sx={{ width: { xs: "100%", sm: "auto" } }}>{status}</Button>) : null}
          </Box>
        </Paper>
      ) : null}

      <Menu anchorEl={columnsAnchor} open={Boolean(columnsAnchor)} onClose={() => setColumnsAnchor(null)}>
        {([ ["status", t("settingsColumnStatus")], ["dateApplied", t("settingsColumnDateApplied")], ["daysSince", t("settingsColumnDays")], ["jobUrl", t("settingsColumnJobUrl")] ] as const).map(([key, label]) => (
          <MenuItem key={key} onClick={() => onColumnsChange({ ...columns, [key]: !columns[key] })}>
            <Checkbox checked={columns[key]} />
            {label}
          </MenuItem>
        ))}
      </Menu>

      <ViewStateNotice
        error={jobsResource.error}
        title={mode === "trash" ? t("jobTableTrashLoadFailed") : t("jobTableJobsLoadFailed")}
        description={mode === "trash" ? t("jobTableTrashLoadFailedBody") : t("jobTableJobsLoadFailedBody")}
        onRetry={jobsResource.reload}
      />
      {companiesError ? (
        <ViewStateNotice
          error={companiesError}
          title={t("jobTableCompanyFiltersLoadFailed")}
          description={t("jobTableCompanyFiltersLoadFailedBody")}
          onRetry={reloadCompanies}
          compact
        />
      ) : null}

      <Paper
        sx={{
          mt: 2,
          overflow: "hidden",
          borderRadius: 4,
          border: "none",
          boxShadow: "0px 1px 2px 0px rgba(15,23,42,0.04), 0px 8px 24px -12px rgba(15,23,42,0.12)",
        }}
      >
        {isMobile ? (
          <Stack spacing={1.25} sx={{ p: 1.25 }}>
            <Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 1, px: 0.5 }}>
              <FormControlLabel control={<Checkbox checked={selectedAllOnPage} indeterminate={selectedIds.length > 0 && !selectedAllOnPage} onChange={(e) => toggleSelectAll(e.target.checked)} />} label={t("jobTableSelectAll")} sx={{ mr: 0 }} />
            </Box>

            {jobsResource.loading ? <Typography sx={{ py: 2, textAlign: "center" }}>{t("loading")}</Typography> : null}
            {!jobsResource.loading && !jobsResource.error && rowModels.map(({ job, toneName, actionSignals, tags, appliedDateLabel, isSelected }) => {
              const compactTags = tags.slice(0, 6);
              return (
                <Paper
                  key={job.id}
                  data-job-row-id={job.id}
                  role={mode === "jobs" && !job.isDeleted ? "link" : undefined}
                  tabIndex={mode === "jobs" && !job.isDeleted ? 0 : undefined}
                  aria-label={mode === "jobs" && !job.isDeleted ? `Open ${job.jobTitle} at ${job.company?.name ?? "company"}` : undefined}
                  onClick={(event) => {
                    if (mode === "jobs" && !job.isDeleted && !isInteractiveTarget(event.target)) openJob(job.id);
                  }}
                  onKeyDown={(event) => {
                    if (mode === "jobs" && !job.isDeleted && event.target === event.currentTarget && (event.key === "Enter" || event.key === " ")) {
                      event.preventDefault();
                      openJob(job.id);
                    }
                  }}
                  sx={{
                    p: 1.5,
                    borderRadius: 3.5,
                    cursor: mode === "jobs" && !job.isDeleted ? "pointer" : "default",
                    backgroundColor: alpha(theme.palette.primary.main, 0.03),
                    borderColor: alpha(theme.palette.primary.main, 0.08),
                    boxShadow: `0 10px 24px ${alpha(theme.palette.common.black, theme.palette.mode === "dark" ? 0.18 : 0.06)}`,
                    "&:hover": mode === "jobs" && !job.isDeleted ? { backgroundColor: "action.hover" } : undefined,
                    "&:focus-visible": { outline: "3px solid", outlineColor: "primary.main", outlineOffset: 2 },
                  }}
                >
                  <Stack spacing={1.25}>
                    <Box sx={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 1 }}>
                      <Box sx={{ display: "flex", alignItems: "flex-start", gap: 1, minWidth: 0, flex: 1 }}>
                        <Checkbox checked={isSelected} onChange={(e) => toggleSelected(job.id, e.target.checked)} sx={{ mt: -0.5, ml: -1 }} />
                        <Box sx={{ minWidth: 0 }}>
                          <Typography variant="body2" sx={{ color: "text.secondary", overflowWrap: "anywhere" }}>
                            {job.company?.name ?? t("jobTableCompany")}
                          </Typography>
                          <Typography sx={{ fontWeight: 900, fontSize: 21, lineHeight: 1.1, letterSpacing: -0.4, textWrap: "balance", overflowWrap: "anywhere" }}>
                            {job.jobTitle}
                          </Typography>
                        </Box>
                      </Box>
                      {columns.status ? <Chip label={statusLabel(t, job.status)} size="small" color={toneName as any} sx={{ fontWeight: 800 }} /> : null}
                    </Box>

                    <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap" }}>
                      {actionSignals.map((signal) => (
                        <Chip
                          key={`${job.id}-${signal.label}-${signal.detail}`}
                          size="small"
                          label={signal.label}
                          color={signal.color}
                          variant={signal.variant === "contained" ? "filled" : "outlined"}
                          title={signal.detail}
                          clickable
                          onClick={signal.onClick}
                          sx={{ fontWeight: 700 }}
                        />
                      ))}
                    </Box>

                    <Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 1.25 }}>
                      {columns.dateApplied ? (
                        <Box>
                          <Typography variant="overline" sx={{ color: "text.secondary" }}>{t("jobTableDateApplied")}</Typography>
                          <Typography variant="body2" sx={{ fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>{appliedDateLabel}</Typography>
                        </Box>
                      ) : null}
                      {columns.daysSince ? (
                        <Box>
                          <Typography variant="overline" sx={{ color: "text.secondary" }}>{t("jobTableDays")}</Typography>
                          <Typography variant="body2" sx={{ fontWeight: 700, fontVariantNumeric: "tabular-nums" }}>{job.daysSince}</Typography>
                        </Box>
                      ) : null}
                      <Box>
                        <Typography variant="overline" sx={{ color: "text.secondary" }}>{t("jobTableLocation")}</Typography>
                        <Typography variant="body2" sx={{ fontWeight: 600 }}>{job.location ?? "-"}</Typography>
                      </Box>
                      <Box>
                        <Typography variant="overline" sx={{ color: "text.secondary" }}>{t("addJobModalSalary")}</Typography>
                        <Typography variant="body2" sx={{ fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>{formatSalary(job) ?? "-"}</Typography>
                      </Box>
                    </Box>

                    {columns.jobUrl && job.jobUrl ? (
                      <Box>
                        <Typography variant="overline" sx={{ color: "text.secondary" }}>{t("settingsColumnJobUrl")}</Typography>
                        <Typography variant="body2"><a href={job.jobUrl} target="_blank" rel="noreferrer">{t("jobTableOpenListing")}</a></Typography>
                      </Box>
                    ) : null}

                    {compactTags.length > 0 ? (
                      <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap" }}>
                        {compactTags.map((tag) => <Chip key={tag} size="small" label={tag} sx={{ borderRadius: 999 }} />)}
                      </Box>
                    ) : null}

                    <Box sx={{ display: "grid", gridTemplateColumns: "repeat(2, minmax(0, 1fr))", gap: 1 }}>
                      <Button variant="outlined" startIcon={<EditOutlinedIcon />} onClick={() => setEditJobId(job.id)} sx={{ minHeight: 42, fontWeight: 700 }}>
                        {t("jobTableEdit")}
                      </Button>
                      <Button variant="outlined" startIcon={<MoreHorizIcon />} onClick={(e) => { setStatusJobId(job.id); setStatusAnchor(e.currentTarget); }} sx={{ minHeight: 42, fontWeight: 700 }}>
                        {t("jobTableQuickStatus")}
                      </Button>
                      {(mode === "trash" || (includeDeleted && job.isDeleted)) ? (
                        <Button variant="outlined" startIcon={<RestoreFromTrashOutlinedIcon />} onClick={() => void restore(job.id)} sx={{ minHeight: 42, fontWeight: 700 }}>
                          {t("jobTableRestore")}
                        </Button>
                      ) : (
                        <Button color="error" variant="outlined" startIcon={<DeleteOutlineIcon />} onClick={() => void softDelete(job)} sx={{ minHeight: 42, fontWeight: 700 }}>
                          {t("jobTableSoftDelete")}
                        </Button>
                      )}
                    </Box>
                  </Stack>
                </Paper>
              );
            })}
            {filteredJobs.length === 0 && !jobsResource.loading && !jobsResource.error ? (
              <EmptyJobsState firstTime={isFirstTimeEmpty} onOpenSettings={() => navigate("/settings")} t={t} />
            ) : null}
          </Stack>
        ) : (
          <Box sx={{ overflowX: "auto" }}>
            <Table size="small" sx={{ minWidth: 980 }}>
              <TableHead>
                <TableRow>
                  <TableCell padding="checkbox"><Checkbox inputProps={{ "aria-label": t("jobTableSelectAll") }} checked={selectedAllOnPage} indeterminate={selectedIds.length > 0 && !selectedAllOnPage} onChange={(e) => toggleSelectAll(e.target.checked)} /></TableCell>
                  <TableCell sortDirection={sortBy === "company" ? sortDir : false}><TableSortLabel active={sortBy === "company"} direction={sortBy === "company" ? sortDir : "asc"} onClick={() => requestSort("company")}>{t("jobTableCompany")}</TableSortLabel></TableCell>
                  <TableCell sortDirection={sortBy === "jobTitle" ? sortDir : false}><TableSortLabel active={sortBy === "jobTitle"} direction={sortBy === "jobTitle" ? sortDir : "asc"} onClick={() => requestSort("jobTitle")}>{t("jobTableRole")}</TableSortLabel></TableCell>
                  <TableCell sortDirection={sortBy === "location" ? sortDir : false}><TableSortLabel active={sortBy === "location"} direction={sortBy === "location" ? sortDir : "asc"} onClick={() => requestSort("location")}>{t("jobTableLocation")}</TableSortLabel></TableCell>
                  {columns.status ? <TableCell sortDirection={sortBy === "status" ? sortDir : false}><TableSortLabel active={sortBy === "status"} direction={sortBy === "status" ? sortDir : "asc"} onClick={() => requestSort("status")}>{t("jobTableStatus")}</TableSortLabel></TableCell> : null}
                  {columns.dateApplied ? <TableCell sortDirection={sortBy === "dateApplied" ? sortDir : false}><TableSortLabel active={sortBy === "dateApplied"} direction={sortBy === "dateApplied" ? sortDir : "asc"} onClick={() => requestSort("dateApplied")}>{t("jobTableDateApplied")}</TableSortLabel></TableCell> : null}
                  {columns.daysSince ? <TableCell sortDirection={sortBy === "daysSince" ? sortDir : false}><TableSortLabel active={sortBy === "daysSince"} direction={sortBy === "daysSince" ? sortDir : "asc"} onClick={() => requestSort("daysSince")}>{t("jobTableDays")}</TableSortLabel></TableCell> : null}
                  <TableCell>{t("jobDetailsDeadline")}</TableCell>
                  {columns.jobUrl ? <TableCell>{t("settingsColumnJobUrl")}</TableCell> : null}
                  <TableCell align="right">{t("jobTableActions")}</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {jobsResource.loading ? <TableRow><TableCell colSpan={visibleDesktopColumns}><Typography sx={{ py: 2, textAlign: "center" }}>{t("loading")}</Typography></TableCell></TableRow> : null}
                {!jobsResource.loading && !jobsResource.error && rowModels.map(({ job, toneName, actionSignals, appliedDateLabel, isSelected }) => {
                  const tone = toneName === "error" ? theme.palette.error.main : toneName === "warning" ? theme.palette.warning.main : toneName === "success" ? theme.palette.success.main : toneName === "info" ? theme.palette.info.main : theme.palette.primary.main;
                  return (
                      <TableRow
                        key={job.id}
                        data-job-row-id={job.id}
                        hover={mode === "jobs" && !job.isDeleted}
                        tabIndex={mode === "jobs" && !job.isDeleted ? 0 : undefined}
                        aria-label={mode === "jobs" && !job.isDeleted ? `Open ${job.jobTitle} at ${job.company?.name ?? "company"}` : undefined}
                        onClick={(event) => {
                          if (mode === "jobs" && !job.isDeleted && !isInteractiveTarget(event.target)) openJob(job.id);
                        }}
                        onKeyDown={(event) => {
                          if (mode === "jobs" && !job.isDeleted && event.target === event.currentTarget && (event.key === "Enter" || event.key === " ")) {
                            event.preventDefault();
                            openJob(job.id);
                          }
                        }}
                        sx={{
                          cursor: mode === "jobs" && !job.isDeleted ? "pointer" : "default",
                          backgroundColor: alpha(tone, theme.palette.mode === "dark" ? 0.1 : 0.06),
                          "&:focus-visible": { outline: "3px solid", outlineColor: "primary.main", outlineOffset: -3 },
                        }}
                      >
                        <TableCell padding="checkbox"><Checkbox inputProps={{ "aria-label": t("jobTableSelectJob", { title: job.jobTitle }) }} checked={isSelected} onChange={(e) => toggleSelected(job.id, e.target.checked)} /></TableCell>
                        <TableCell sx={{ minWidth: 140, fontWeight: 700 }}>{job.company?.name ?? ""}</TableCell>
                        <TableCell>
                          <Box sx={{ display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }}>
                            <Typography component="span" sx={{ fontWeight: 800, overflowWrap: "anywhere" }}>{job.jobTitle}</Typography>
                            {actionSignals.map((signal) => (
                              <Chip
                                key={`${job.id}-${signal.label}-${signal.detail}`}
                                size="small"
                                label={signal.label}
                                color={signal.color}
                                variant={signal.variant === "contained" ? "filled" : "outlined"}
                                title={signal.detail}
                                sx={{ fontWeight: 800, cursor: "pointer" }}
                                clickable
                                onClick={signal.onClick}
                                aria-label={`${job.jobTitle} — ${signal.label} signal`}
                              />
                            ))}
                          </Box>
                        </TableCell>
                        <TableCell sx={{ minWidth: 130 }}>{job.location || "—"}</TableCell>
                        {columns.status ? <TableCell><Chip label={statusLabel(t, job.status)} size="small" color={toneName as any} /></TableCell> : null}
                        {columns.dateApplied ? <TableCell>{appliedDateLabel}</TableCell> : null}
                        {columns.daysSince ? <TableCell>{job.daysSince ?? "—"}</TableCell> : null}
                        <TableCell>{job.deadline ? new Date(job.deadline).toLocaleDateString() : "—"}</TableCell>
                        {columns.jobUrl ? <TableCell>{job.jobUrl ? <a href={job.jobUrl} target="_blank" rel="noreferrer">{t("jobTableLink")}</a> : ""}</TableCell> : null}
                        <TableCell align="right">
                            <Box sx={{ display: "flex", justifyContent: "flex-end", gap: 0.5, whiteSpace: "nowrap" }}>
                              <Tooltip title={t("jobTableEdit")}><IconButton size="small" aria-label={`${t("jobTableEdit")}: ${job.jobTitle}`} onClick={() => setEditJobId(job.id)}><EditOutlinedIcon fontSize="small" /></IconButton></Tooltip>
                              <Tooltip title={t("jobTableQuickStatus")}><IconButton size="small" aria-label={`${t("jobTableQuickStatus")}: ${job.jobTitle}`} onClick={(e) => { setStatusJobId(job.id); setStatusAnchor(e.currentTarget); }}><MoreHorizIcon fontSize="small" /></IconButton></Tooltip>
                              {(mode === "trash" || (includeDeleted && job.isDeleted)) ? <Tooltip title={t("jobTableRestore")}><IconButton size="small" aria-label={`${t("jobTableRestore")}: ${job.jobTitle}`} onClick={() => void restore(job.id)}><RestoreFromTrashOutlinedIcon fontSize="small" /></IconButton></Tooltip> : <Tooltip title={t("jobTableSoftDelete")}><IconButton size="small" aria-label={`${t("jobTableSoftDelete")}: ${job.jobTitle}`} onClick={() => void softDelete(job)}><DeleteOutlineIcon fontSize="small" /></IconButton></Tooltip>}
                            </Box>
                        </TableCell>
                      </TableRow>
                  );
                })}
                {filteredJobs.length === 0 && !jobsResource.loading && !jobsResource.error ? (
                  <TableRow><TableCell colSpan={visibleDesktopColumns}><EmptyJobsState firstTime={isFirstTimeEmpty} onOpenSettings={() => navigate("/settings")} t={t} /></TableCell></TableRow>
                ) : null}
              </TableBody>
            </Table>
          </Box>
        )}
        <TablePagination component="div" count={total} page={page} onPageChange={(_, next) => { setPage(next); updateListRoute({ page: next > 0 ? String(next + 1) : null }); }} rowsPerPage={pageSize} onRowsPerPageChange={(e) => { onPageSizeChange(Number(e.target.value) as 15 | 20 | 25); setPage(0); updateListRoute({ page: null }); }} rowsPerPageOptions={[15, 20, 25]} />
      </Paper>

      <EditJobDialog open={editJobId !== null} jobId={editJobId} onClose={() => setEditJobId(null)} onSaved={() => setReloadToken((token) => token + 1)} />
      <Menu anchorEl={statusAnchor} open={Boolean(statusAnchor)} onClose={() => { setStatusAnchor(null); setStatusJobId(null); }}>
        {statusOptions.map((status) => <MenuItem key={status} onClick={() => { if (statusJobId) void setStatusQuick(statusJobId, status); setStatusAnchor(null); setStatusJobId(null); }}>{t("jobTableSetStatus", { status })}</MenuItem>)}
      </Menu>
    </Box>
  );
}
