import React, { useEffect, useMemo, useRef, useState } from "react";

import { DatePicker } from "@mui/x-date-pickers/DatePicker";

import {
  Alert,
  Autocomplete,
  Box,
  Button,
  Checkbox,
  Chip,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  FormControlLabel,
  IconButton,
  List,
  ListItem,
  ListItemText,
  MenuItem,
  Step,
  StepLabel,
  Stepper,
  TextField,
  Typography,
} from "@mui/material";

import CloseIcon from "@mui/icons-material/Close";
import { useAccountPlan } from "../accountPlan";
import UploadFileOutlinedIcon from "@mui/icons-material/UploadFileOutlined";

import { api, getApiErrorMessage } from "../api";
import { Company, JobImportResult } from "../types";
import { invalidateCompaniesCache, useCompanies } from "../hooks/useCompanies";
import { useToast } from "../toast";
import { useI18n } from "../i18n/I18nProvider";
import { PIPELINE_STATUSES, statusLabel as pipelineStatusLabel } from "../pipeline";
import TagsInput from "./TagsInput";

interface Props {
  open: boolean;
  onClose: () => void;
  onCreated: () => void;
  initialUrl?: string;
}

type DuplicateCandidate = {
  id: number;
  jobTitle: string;
  company: string;
  jobUrl?: string | null;
  status: string;
  dateApplied: string;
  reason: string;
};

type DuplicateCheckResult = {
  hasDuplicates: boolean;
  matches: DuplicateCandidate[];
};

type CreatedJobResponse = {
  id?: number;
};

type AttachmentBucketKey = "resume" | "coverLetter" | "portfolio" | "other";
type AttachmentBuckets = Record<AttachmentBucketKey, File[]>;

const ACCEPTED_DOCUMENT_TYPES = ".pdf,.doc,.docx,.txt,.md,image/*,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,text/plain,text/markdown";
const FIELD_SX = { "& .MuiInputBase-root": { minHeight: 56 } };
const PICKER_TEXT_FIELD_PROPS = { fullWidth: true, sx: FIELD_SX };

function getTodayIso() {
  return new Date().toISOString().slice(0, 10);
}

function parsePickerDate(value?: string | null): Date | null {
  if (!value) return null;
  const parsed = new Date(value);
  return Number.isNaN(+parsed) ? null : parsed;
}

function toPickerIso(value: Date | null) {
  if (!value || Number.isNaN(+value)) return "";
  return value.toISOString().slice(0, 10);
}

function emptyAttachmentBuckets(): AttachmentBuckets {
  return {
    resume: [],
    coverLetter: [],
    portfolio: [],
    other: [],
  };
}

function normalizeLanguage(value?: string | null) {
  const raw = (value || "").trim().toLowerCase();
  if (!raw) return "";
  if (["en", "eng", "english"].includes(raw)) return "en";
  if (["no", "nb", "nb-no", "nn", "norwegian", "norwegian bokmål", "bokmal", "bokmål"].includes(raw)) return "nb";
  return raw;
}

export default function AddJobModal({ open, onClose, onCreated, initialUrl }: Props) {
  const { canUseAi } = useAccountPlan();
  const { toast } = useToast();
  const { t, language } = useI18n();

  const [saving, setSaving] = useState(false);
  const [activeStep, setActiveStep] = useState(0);
  const [importing, setImporting] = useState(false);
  const [duplicateCheck, setDuplicateCheck] = useState<DuplicateCheckResult | null>(null);

  const { companies: cachedCompanies } = useCompanies();
  const [companies, setCompanies] = useState<Company[]>([]);

  const [company, setCompany] = useState<Company | null>(null);
  const [companyInput, setCompanyInput] = useState("");
  const [newCompanyLocation, setNewCompanyLocation] = useState("");
  const [newCompanySource, setNewCompanySource] = useState("");

  const [dateApplied, setDateApplied] = useState(() => getTodayIso());
  const [jobTitle, setJobTitle] = useState("");
  const [status, setStatus] = useState<(typeof PIPELINE_STATUSES)[number]>("Saved");
  const [location, setLocation] = useState("");
  const [salary, setSalary] = useState("");
  const [salaryMin, setSalaryMin] = useState("");
  const [salaryMax, setSalaryMax] = useState("");
  const [salaryCurrency, setSalaryCurrency] = useState("");
  const [salaryPeriod, setSalaryPeriod] = useState("");
  const [jobUrl, setJobUrl] = useState("");
  const [jobSource, setJobSource] = useState("");
  const [countryCode, setCountryCode] = useState("");
  const [deadline, setDeadline] = useState("");

  const [description, setDescription] = useState("");
  const [translatedDescription, setTranslatedDescription] = useState("");
  const [descriptionLanguage, setDescriptionLanguage] = useState("");

  const [tags, setTags] = useState<string[]>([]);
  const [notes, setNotes] = useState("");
  const [generateTailoredCv, setGenerateTailoredCv] = useState(false);
  const [attachments, setAttachments] = useState<AttachmentBuckets>(() => emptyAttachmentBuckets());

  useEffect(() => {
    setCompanies(cachedCompanies);
  }, [cachedCompanies]);

  // Quick-capture: when opened with a URL (from the bookmarklet), prefill and auto-import once.
  const autoImportedUrlRef = useRef<string | null>(null);
  useEffect(() => {
    if (!open) {
      autoImportedUrlRef.current = null;
      return;
    }
    const url = initialUrl?.trim();
    if (!url || autoImportedUrlRef.current === url) return;
    autoImportedUrlRef.current = url;
    setJobUrl(url);
    void importFromUrl(url);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open, initialUrl]);

  const resetForm = () => {
    setActiveStep(0);
    setCompany(null);
    setCompanyInput("");
    setNewCompanyLocation("");
    setNewCompanySource("");
    setDateApplied(getTodayIso());
    setJobTitle("");
    setStatus("Saved");
    setLocation("");
    setSalary("");
    setSalaryMin("");
    setSalaryMax("");
    setSalaryCurrency("");
    setSalaryPeriod("");
    setJobUrl("");
    setJobSource("");
    setCountryCode("");
    setDeadline("");
    setDescription("");
    setTranslatedDescription("");
    setDescriptionLanguage("");
    setTags([]);
    setNotes("");
    setGenerateTailoredCv(false);
    setAttachments(emptyAttachmentBuckets());
    setDuplicateCheck(null);
  };

  const normalizedCompanyName = companyInput.trim();
  const matchingCompany = useMemo(() => {
    if (!normalizedCompanyName) return null;
    return companies.find((c) => c.name.toLowerCase() === normalizedCompanyName.toLowerCase()) ?? null;
  }, [companies, normalizedCompanyName]);

  const selectedCompanyId = company?.id ?? matchingCompany?.id ?? 0;
  const showNewCompanyFields = !company && !!normalizedCompanyName && !matchingCompany;
  const preferredLanguage = normalizeLanguage(language);
  const sourceLanguage = normalizeLanguage(descriptionLanguage);
  const shouldShowTranslatedDescription = Boolean(sourceLanguage && preferredLanguage && sourceLanguage !== preferredLanguage);
  const attachmentCount = Object.values(attachments).reduce((sum, files) => sum + files.length, 0);

  useEffect(() => {
    if (!open) return;

    const title = jobTitle.trim();
    const url = jobUrl.trim();
    if (!selectedCompanyId && !url) {
      setDuplicateCheck(null);
      return;
    }
    if (!title && !url) {
      setDuplicateCheck(null);
      return;
    }

    const timeout = window.setTimeout(() => {
      api
        .get<DuplicateCheckResult>("/jobapplications/duplicate-check", {
          params: {
            companyId: selectedCompanyId || undefined,
            jobTitle: title || undefined,
            jobUrl: url || undefined,
          },
        })
        .then((r) => setDuplicateCheck(r.data))
        .catch(() => setDuplicateCheck(null));
    }, 350);

    return () => window.clearTimeout(timeout);
  }, [open, selectedCompanyId, jobTitle, jobUrl]);

  const createCompany = async (): Promise<Company | null> => {
    if (!normalizedCompanyName) return null;

    const payload: Partial<Company> = { name: normalizedCompanyName };
    if (newCompanyLocation.trim()) payload.location = newCompanyLocation.trim();
    if (newCompanySource.trim()) payload.source = newCompanySource.trim();

    try {
      const res = await api.post<Company>("/companies", payload);
      setCompany(res.data);
      setCompanyInput(res.data.name);
      setCompanies((prev) => [...prev, res.data]);
      invalidateCompaniesCache();
      setNewCompanyLocation("");
      setNewCompanySource("");
      return res.data;
    } catch (error: any) {
      toast(getApiErrorMessage(error, t("addJobModalFailedCreateCompany")), "error");
      return null;
    }
  };

  const importFromUrl = async (urlArg?: string) => {
    if (importing) return;
    const url = (urlArg ?? jobUrl).trim();
    if (!url) {
      toast(t("addJobModalPasteUrlFirst"), "warning");
      return;
    }

    setImporting(true);
    try {
      const res = await api.post<JobImportResult>("/jobimport/preview", { url });
      const r = res.data;
      if (!r?.success) throw new Error(r?.error || t("addJobModalImportFailed"));

      if (r.title) setJobTitle(r.title);
      if (r.location) setLocation(r.location);
      if (r.company) {
        setCompany(null);
        setCompanyInput(r.company);
        try {
          if (r.sourceUrl) setNewCompanySource(new URL(r.sourceUrl).hostname);
        } catch {
          // ignore
        }
      }

      setJobSource(r.source || "");
      setCountryCode(r.countryCode || "");
      setDescription(r.description || "");
      setTranslatedDescription(r.translatedDescription || "");
      setDescriptionLanguage(r.language || "");
      setTags(r.tags || []);
      setDeadline(r.deadline ? r.deadline.slice(0, 10) : "");

      toast(t("addJobModalImported"), "success");
      setActiveStep(1);
    } catch (e: any) {
      toast(e?.message || t("addJobModalImportFailed"), "error");
    } finally {
      setImporting(false);
    }
  };

  const uploadAttachments = async (jobId: number) => {
    const files = Object.values(attachments).flat();
    if (!files.length) return;

    const data = new FormData();
    files.forEach((file) => data.append("files", file));
    data.append("jobId", String(jobId));

    await api.post("/attachments", data, {
      headers: { "Content-Type": "multipart/form-data" },
    });
  };

  const createJob = async (addAnother = false) => {
    if (saving) return;

    setSaving(true);
    try {
      let selectedCompany = company ?? matchingCompany;
      if (!selectedCompany && normalizedCompanyName) {
        selectedCompany = await createCompany();
      }
      if (!selectedCompany) {
        toast(t("addJobModalSelectCompany"), "warning");
        return;
      }

      const response = await api.post<CreatedJobResponse>("/jobapplications", {
        jobTitle,
        companyId: selectedCompany.id,
        status,
        location,
        salary,
        salaryMin: salaryMin.trim() ? Number(salaryMin) : null,
        salaryMax: salaryMax.trim() ? Number(salaryMax) : null,
        salaryCurrency: salaryCurrency.trim() || null,
        salaryPeriod: salaryPeriod || null,
        nextAction: null,
        followUpAt: null,
        jobUrl,
        source: jobSource || null,
        countryCode: countryCode || null,
        description: description || null,
        translatedDescription: shouldShowTranslatedDescription ? translatedDescription || null : null,
        descriptionLanguage: descriptionLanguage || null,
        tags: tags.length ? JSON.stringify(tags) : null,
        deadline: deadline || null,
        notes,
        coverLetterText: null,
        dateApplied,
      });

      if (response.data?.id && generateTailoredCv && canUseAi) {
        try {
          await api.post(`/jobapplications/${response.data.id}/generate-tailored-cv-draft`);
        } catch (error: any) {
          toast(getApiErrorMessage(error, t("addJobModalTailoredCvFailed")), "warning");
        }
      }

      if (response.data?.id && attachmentCount > 0) {
        try {
          await uploadAttachments(response.data.id);
          toast(t("addJobModalJobAndFilesAdded"), "success");
        } catch {
          toast(t("addJobModalJobCreatedUploadFailed"), "warning");
        }
      } else if (attachmentCount > 0) {
        toast(t("addJobModalJobCreatedFilesNotAttached"), "warning");
      } else {
        toast(t("addJobModalJobAdded"), "success");
      }

      onCreated();
      resetForm();
      if (!addAnother) {
        onClose();
      }
    } catch {
      toast(t("addJobModalFailedAddJob"), "error");
    } finally {
      setSaving(false);
    }
  };

  const canSave = normalizedCompanyName.length > 0 && jobTitle.trim().length > 0;
  const steps = [
    t("addJobModalStepAddJob"),
    t("addJobModalStepReview"),
    t("addJobModalResume"),
    t("addJobModalCoverLetter"),
    t("addJobModalPortfolio"),
    t("addJobModalStepAdditionalFiles"),
  ];
  const optionalStep = activeStep >= 2 && activeStep <= 5;

  const setFilesForBucket = (bucket: AttachmentBucketKey, files: FileList | null) => {
    setAttachments((prev) => ({
      ...prev,
      [bucket]: files ? Array.from(files) : [],
    }));
  };

  const filesLabel = (files: File[]) => {
    if (files.length === 0) return t("addJobModalNoFilesSelected");
    if (files.length === 1) return files[0].name;
    return t("addJobModalFilesSelected", { count: files.length });
  };

  const uploadField = (
    bucket: AttachmentBucketKey,
    label: string,
    helperText: string,
  ) => (
    <Box sx={{ p: 1.5, borderRadius: 2, border: "none", boxShadow: "0px 1px 2px 0px rgba(15,23,42,0.04), 0px 8px 24px -12px rgba(15,23,42,0.12)", backgroundColor: "background.paper" }}>
      <Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 1, flexWrap: "wrap" }}>
        <Box>
          <Typography sx={{ fontWeight: 800 }}>{label}</Typography>
          <Typography variant="body2" sx={{ color: "text.secondary" }}>{helperText}</Typography>
        </Box>
        <Button component="label" variant="outlined" size="small" startIcon={<UploadFileOutlinedIcon />}>
          {t("addJobModalChooseFiles")}
          <input hidden type="file" multiple accept={ACCEPTED_DOCUMENT_TYPES} onChange={(e) => setFilesForBucket(bucket, e.target.files)} />
        </Button>
      </Box>
      <Typography variant="caption" sx={{ display: "block", mt: 1, color: "text.secondary" }}>
        {filesLabel(attachments[bucket])}
      </Typography>
    </Box>
  );

  return (
    <Dialog open={open} onClose={onClose} fullWidth maxWidth="md">
      <DialogTitle sx={{ pr: 6 }}>
        {t("addJob")}
        <IconButton aria-label={t("close")} onClick={onClose} sx={{ position: "absolute", right: 12, top: 12 }}>
          <CloseIcon />
        </IconButton>
      </DialogTitle>
      <DialogContent dividers>
        <Stepper activeStep={activeStep} alternativeLabel sx={{ mb: 3, display: { xs: "none", sm: "flex" } }}>
          {steps.map((label) => <Step key={label}><StepLabel>{label}</StepLabel></Step>)}
        </Stepper>
        <Typography variant="subtitle2" sx={{ display: { xs: "block", sm: "none" }, mb: 2 }}>
          {t("addJobModalStepProgress", { current: activeStep + 1, total: steps.length, step: steps[activeStep] })}
        </Typography>

        {activeStep === 0 ? <Box sx={{ display: "grid", gap: 2 }}>
          <Box>
            <Typography variant="h6" sx={{ fontWeight: 900 }}>{t("addJobModalStartWithAdvert")}</Typography>
            <Typography variant="body2" sx={{ color: "text.secondary", mt: 0.5 }}>
              {t("addJobModalStartWithAdvertBody")}
            </Typography>
          </Box>
          <TextField label={t("addJobModalJobUrl")} value={jobUrl} onChange={(e) => setJobUrl(e.target.value)} fullWidth sx={FIELD_SX} />
          <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
            <Button variant="contained" onClick={() => void importFromUrl()} disabled={importing || !jobUrl.trim()}>
              {importing ? t("addJobModalImporting") : t("addJobModalImportFromUrl")}
            </Button>
            <Button onClick={() => setActiveStep(1)}>{t("addJobModalEnterManually")}</Button>
          </Box>
        </Box> : null}

        {activeStep === 1 ? <>
        <Typography variant="overline" sx={{ display: "block", mt: 0.5 }}>
          {t("addJobModalCompanySection")}
        </Typography>

        <Autocomplete<Company, false, false, true>
          options={companies}
          getOptionLabel={(c) => (typeof c === "string" ? c : c.name)}
          value={company}
          freeSolo
          inputValue={companyInput}
          onInputChange={(_, v) => {
            setCompanyInput(v);
            if (!v) setCompany(null);
          }}
          onChange={(_, v) => {
            if (typeof v === "string") {
              setCompany(null);
              setCompanyInput(v);
              return;
            }
            setCompany(v);
            setCompanyInput(v?.name ?? "");
            if (v) {
              setNewCompanyLocation("");
              setNewCompanySource("");
            }
          }}
          renderInput={(params) => <TextField {...params} label={t("company")} />}
        />

        {showNewCompanyFields ? (
          <Box sx={{ mt: 1, display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 2 }}>
            <TextField label={t("addJobModalCompanyLocation")} value={newCompanyLocation} onChange={(e) => setNewCompanyLocation(e.target.value)} />
            <TextField label={t("addJobModalCompanySource")} value={newCompanySource} onChange={(e) => setNewCompanySource(e.target.value)} />
            <Box sx={{ gridColumn: "1 / -1" }}>
              <Button variant="outlined" onClick={() => void createCompany()}>
                {t("addJobModalCreateCompany", { name: normalizedCompanyName })}
              </Button>
            </Box>
          </Box>
        ) : null}

        {duplicateCheck?.hasDuplicates ? (
          <Alert severity="warning" sx={{ mt: 2 }}>
            <Typography sx={{ fontWeight: 800, mb: 0.75 }}>{t("addJobModalPossibleDuplicates")}</Typography>
            <List dense sx={{ py: 0 }}>
              {duplicateCheck.matches.map((match) => (
                <ListItem key={match.id} sx={{ px: 0 }}>
                  <ListItemText
                    primary={`${match.company} - ${match.jobTitle}`}
                    secondary={`${match.reason} • ${match.status} • ${new Date(match.dateApplied).toLocaleDateString(language === "nb" ? "nb-NO" : "en")}`}
                  />
                </ListItem>
              ))}
            </List>
          </Alert>
        ) : null}

        <Divider sx={{ my: 2 }} />

        <Typography variant="overline" sx={{ display: "block" }}>
          {t("addJobModalJobApplicationSection")}
        </Typography>

        <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 2, mt: 1 }}>
          <TextField label={t("addJobModalJobUrl")} value={jobUrl} onChange={(e) => setJobUrl(e.target.value)} sx={{ ...FIELD_SX, gridColumn: "1 / -1" }} />

          <DatePicker
            label={t("addJobModalDateApplied")}
            value={parsePickerDate(dateApplied)}
            onChange={(value) => setDateApplied(toPickerIso(value))}
            slotProps={{ textField: PICKER_TEXT_FIELD_PROPS }}
          />

          <TextField select label={t("addJobModalStatus")} value={status} onChange={(e) => setStatus(e.target.value as any)} sx={FIELD_SX}>
            {PIPELINE_STATUSES.map((s) => (
              <MenuItem key={s} value={s}>
                {pipelineStatusLabel(t, s)}
              </MenuItem>
            ))}
          </TextField>

          <TextField label={t("addJobModalJobTitle")} value={jobTitle} onChange={(e) => setJobTitle(e.target.value)} sx={FIELD_SX} />
          <TextField label={t("location")} value={location} onChange={(e) => setLocation(e.target.value)} sx={FIELD_SX} />

          <TextField label={t("addJobModalSalary")} value={salary} onChange={(e) => setSalary(e.target.value)} sx={FIELD_SX} />
          <TextField label={t("salaryMinLabel")} type="number" value={salaryMin} onChange={(e) => setSalaryMin(e.target.value)} sx={FIELD_SX} />
          <TextField label={t("salaryMaxLabel")} type="number" value={salaryMax} onChange={(e) => setSalaryMax(e.target.value)} sx={FIELD_SX} />
          <TextField label={t("salaryCurrencyLabel")} value={salaryCurrency} onChange={(e) => setSalaryCurrency(e.target.value)} sx={FIELD_SX} inputProps={{ maxLength: 8 }} />
          <TextField select SelectProps={{ native: true }} label={t("salaryPeriodLabel")} value={salaryPeriod} onChange={(e) => setSalaryPeriod(e.target.value)} sx={FIELD_SX} InputLabelProps={{ shrink: true }}>
            <option value=""></option>
            <option value="year">{t("salaryPeriodYear")}</option>
            <option value="month">{t("salaryPeriodMonth")}</option>
            <option value="hour">{t("salaryPeriodHour")}</option>
          </TextField>
          <DatePicker
            label={t("addJobModalDeadline")}
            value={parsePickerDate(deadline)}
            onChange={(value) => setDeadline(toPickerIso(value))}
            slotProps={{ textField: PICKER_TEXT_FIELD_PROPS }}
          />

          <Box sx={{ gridColumn: "1 / -1" }}>
            <TagsInput value={tags} onChange={setTags} />
          </Box>

          <TextField
            label={t("addJobModalDescriptionOriginal")}
            multiline
            rows={6}
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            helperText={t("characterCount", { count: description.length })}
            sx={{ gridColumn: "1 / -1" }}
          />

          {shouldShowTranslatedDescription ? (
            <TextField
              label={t("addJobModalTranslatedDescription", { language: preferredLanguage.toUpperCase() })}
              multiline
              rows={6}
              value={translatedDescription}
              onChange={(e) => setTranslatedDescription(e.target.value)}
              helperText={t("characterCount", { count: translatedDescription.length })}
              sx={{ gridColumn: "1 / -1" }}
            />
          ) : null}

          <TextField
            label={t("addJobModalDescriptionLanguage")}
            value={descriptionLanguage}
            onChange={(e) => setDescriptionLanguage(e.target.value)}
            helperText={shouldShowTranslatedDescription ? t("addJobModalTranslatedShown", { language: preferredLanguage.toUpperCase() }) : t("addJobModalTranslatedHidden")}
            sx={{ gridColumn: "1 / -1" }}
          />

          <TextField label={t("addJobModalNotes")} multiline rows={3} value={notes} onChange={(e) => setNotes(e.target.value)} helperText={t("characterCount", { count: notes.length })} sx={{ gridColumn: "1 / -1" }} />

        </Box>
        </> : null}

        {activeStep >= 2 ? <Box sx={{ display: "grid", gap: 2 }}>
          <Box>
            <Typography variant="h6" sx={{ fontWeight: 900 }}>{steps[activeStep]}</Typography>
            <Typography variant="body2" sx={{ color: "text.secondary", mt: 0.5 }}>
              {activeStep === 2 ? t("addJobModalCvStepHelp") : null}
              {activeStep === 3 ? t("addJobModalCoverLetterStepHelp") : null}
              {activeStep === 4 ? t("addJobModalPortfolioStepHelp") : null}
              {activeStep === 5 ? t("addJobModalOtherFilesStepHelp") : null}
            </Typography>
          </Box>
          {activeStep === 2 ? <>
            <FormControlLabel control={<Checkbox disabled={!canUseAi} checked={generateTailoredCv && canUseAi} onChange={(event) => setGenerateTailoredCv(event.target.checked)} />} label={canUseAi ? t("addJobModalGenerateTailoredCv") : t("addJobModalTailoredCvRequiresPro")} />
            <Typography variant="caption" sx={{ color: "text.secondary", mt: -1 }}>{canUseAi ? t("addJobModalTailoredCvHelp") : t("addJobModalNoAiHelp")}</Typography>
            {uploadField("resume", t("addJobModalResume"), t("addJobModalResumeHelp"))}
          </> : null}
          {activeStep === 3 ? uploadField("coverLetter", t("addJobModalCoverLetter"), t("addJobModalCoverLetterHelp")) : null}
          {activeStep === 4 ? uploadField("portfolio", t("addJobModalPortfolio"), t("addJobModalPortfolioHelp")) : null}
          {activeStep === 5 ? uploadField("other", t("addJobModalOtherFiles"), t("addJobModalOtherFilesHelp")) : null}
          <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
            <Chip size="small" variant="outlined" label={attachmentCount === 1 ? t("addJobModalFileReady", { count: attachmentCount }) : t("addJobModalFilesReady", { count: attachmentCount })} />
            <Chip size="small" variant="outlined" label={t("addJobModalPreferredFiles")} />
          </Box>
        </Box> : null}
      </DialogContent>
      <DialogActions sx={{ px: 3, py: 2, justifyContent: "space-between", flexWrap: "wrap", gap: 1.5 }}>
        <Button variant="outlined" onClick={onClose}>{t("close")}</Button>
        <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
          {activeStep > 0 ? <Button onClick={() => setActiveStep((step) => step - 1)} disabled={saving}>{t("back")}</Button> : null}
          {activeStep < steps.length - 1 ? <Button variant="contained" onClick={() => setActiveStep((step) => step + 1)} disabled={saving || (activeStep === 1 && !canSave)}>
            {optionalStep ? t("skipAndContinue") : t("continue")}
          </Button> : <>
            <Button variant="outlined" onClick={() => void createJob(true)} disabled={saving || !canSave}>
              {saving ? t("rulesSaving") : t("createAndAddAnother")}
            </Button>
            <Button variant="contained" onClick={() => void createJob(false)} disabled={saving || !canSave}>
              {saving ? t("rulesSaving") : t("createJob")}
            </Button>
          </>}
        </Box>
      </DialogActions>
    </Dialog>
  );
}
