import {
  toggleAiSelectable,
  toggleMustInclude,
} from "@client/pages/settings/resume-projects-state";
import type { UpdateSettingsInput } from "@shared/settings-schema.js";
import type { ResumeProjectCatalogItem } from "@shared/types.js";
import type React from "react";
import {
  type Path,
  type PathValue,
  useFormContext,
  useWatch,
} from "react-hook-form";
import {
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { clampInt } from "@/lib/utils";

type ResumeSettingsSectionProps = {
  profileProjects: ResumeProjectCatalogItem[];
  lockedCount: number;
  maxProjectsTotal: number;
  localResumeFileConfigured: boolean;
  isLoading: boolean;
  isSaving: boolean;
};

export const ResumeSettingsSection: React.FC<ResumeSettingsSectionProps> = ({
  profileProjects,
  lockedCount,
  maxProjectsTotal,
  localResumeFileConfigured,
  isLoading,
  isSaving,
}) => {
  const {
    control,
    setValue,
    formState: { errors },
  } = useFormContext<UpdateSettingsInput>();
  const localResumeProfilePathValue =
    useWatch({ control, name: "localResumeProfilePath" }) ?? "";
  const resumeProjectsValue = useWatch({ control, name: "resumeProjects" });

  const setDirtyTouchedValue = <TField extends Path<UpdateSettingsInput>>(
    field: TField,
    value: PathValue<UpdateSettingsInput, TField>,
  ) =>
    setValue(field, value, {
      shouldDirty: true,
      shouldTouch: true,
    });

  const hasResumeSource =
    localResumeFileConfigured || Boolean(localResumeProfilePathValue.trim());

  return (
    <AccordionItem value="resume" className="border rounded-lg px-4">
      <AccordionTrigger className="hover:no-underline py-4">
        <span className="text-base font-semibold">Resume</span>
      </AccordionTrigger>
      <AccordionContent className="pb-4 space-y-6">
        <div className="space-y-2 rounded-md border border-dashed p-3">
          <Label htmlFor="local-resume-profile-path">Local resume JSON</Label>
          <Input
            id="local-resume-profile-path"
            type="text"
            autoComplete="off"
            placeholder="/absolute/or/relative/path/to/resume.json"
            value={localResumeProfilePathValue}
            disabled={isLoading || isSaving || localResumeFileConfigured}
            onChange={(e) =>
              setDirtyTouchedValue("localResumeProfilePath", e.target.value)
            }
          />
          <p className="text-muted-foreground text-xs">
            Path to a resume export JSON on the server machine. Used for
            scoring, cover letters, tailoring, and PDF generation. Relative
            paths resolve from the orchestrator working directory.{" "}
            <span className="font-mono">JOBOPS_LOCAL_RESUME_PATH</span> in{" "}
            <span className="font-mono">.env</span> overrides this field when
            set.
          </p>
          {localResumeFileConfigured ? (
            <p className="text-xs text-emerald-600 dark:text-emerald-400">
              A local resume file is configured via environment variable.
            </p>
          ) : null}
        </div>

        {!hasResumeSource ? (
          <div className="rounded-md border border-dashed border-muted-foreground/40 bg-muted/30 px-4 py-3 text-sm text-muted-foreground">
            Set a local resume JSON path to configure project selection and run
            tailoring.
          </div>
        ) : profileProjects.length === 0 ? (
          <div className="rounded-md border border-dashed border-muted-foreground/40 bg-muted/30 px-4 py-3 text-sm text-muted-foreground">
            Save a valid resume path, then reload settings to see projects from
            your resume file.
          </div>
        ) : (
          <div className="space-y-4">
            <div className="space-y-2">
              <div className="text-sm font-medium">Max projects to choose</div>
              <Input
                type="number"
                inputMode="numeric"
                min={lockedCount}
                max={maxProjectsTotal}
                value={resumeProjectsValue?.maxProjects ?? 0}
                onChange={(event) => {
                  if (!resumeProjectsValue) return;
                  const next = Number(event.target.value);
                  const clamped = clampInt(next, lockedCount, maxProjectsTotal);
                  setDirtyTouchedValue("resumeProjects", {
                    ...resumeProjectsValue,
                    maxProjects: clamped,
                  });
                }}
                disabled={isLoading || isSaving || !resumeProjectsValue}
              />
              {errors.resumeProjects?.maxProjects?.message ? (
                <p className="text-xs text-destructive">
                  {errors.resumeProjects.maxProjects.message.toString()}
                </p>
              ) : null}
            </div>

            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="text-xs">Project</TableHead>
                  <TableHead className="text-xs">In resume</TableHead>
                  <TableHead className="text-xs">Must include</TableHead>
                  <TableHead className="text-xs">AI selectable</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {profileProjects.map((project) => {
                  const value = resumeProjectsValue;
                  const locked = Boolean(
                    value?.lockedProjectIds.includes(project.id),
                  );
                  const aiSelectable = Boolean(
                    value?.aiSelectableProjectIds.includes(project.id),
                  );
                  const projectMeta = [project.description, project.date]
                    .filter(Boolean)
                    .join(" · ");

                  return (
                    <TableRow key={project.id}>
                      <TableCell>
                        <div className="space-y-0.5">
                          <div className="font-medium">{project.name}</div>
                          {projectMeta ? (
                            <div className="text-xs text-muted-foreground">
                              {projectMeta}
                            </div>
                          ) : null}
                        </div>
                      </TableCell>
                      <TableCell>
                        {project.isVisibleInBase ? "Yes" : "No"}
                      </TableCell>
                      <TableCell>
                        <Checkbox
                          checked={locked}
                          onCheckedChange={() => {
                            if (!value) return;
                            setDirtyTouchedValue(
                              "resumeProjects",
                              toggleMustInclude({
                                settings: value,
                                projectId: project.id,
                                checked: !locked,
                                maxProjectsTotal,
                              }),
                            );
                          }}
                          disabled={isLoading || isSaving || !value}
                        />
                      </TableCell>
                      <TableCell>
                        <Checkbox
                          checked={locked ? true : aiSelectable}
                          onCheckedChange={() => {
                            if (!value) return;
                            setDirtyTouchedValue(
                              "resumeProjects",
                              toggleAiSelectable({
                                settings: value,
                                projectId: project.id,
                                checked: !aiSelectable,
                              }),
                            );
                          }}
                          disabled={isLoading || isSaving || locked || !value}
                        />
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </div>
        )}
      </AccordionContent>
    </AccordionItem>
  );
};
