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

import { Accordion, AccordionDetails, AccordionSummary, Alert, Avatar, Box, Button, Chip, Dialog, DialogContent, DialogTitle, Divider, FormControl, IconButton, InputLabel, LinearProgress, MenuItem, Paper, Select, TextField, Typography } from "@mui/material";

import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import PhotoCameraOutlinedIcon from "@mui/icons-material/PhotoCameraOutlined";
import ZoomInOutlinedIcon from "@mui/icons-material/ZoomInOutlined";

import { api, getApiErrorMessage } from "../api";
import GoogleAuthCard from "../components/GoogleAuthCard";
import MicrosoftAuthCard from "../components/MicrosoftAuthCard";
import AuthStatusCard from "../components/AuthStatusCard";
import TwoFactorSettingsCard from "../components/TwoFactorSettingsCard";
import SessionsSettingsCard from "../components/SessionsSettingsCard";
import CropImageDialog from "../components/CropImageDialog";
import { useToast } from "../toast";
import { useI18n } from "../i18n/I18nProvider";
import {
  emptyStructuredCv,
  getStructuredCvFieldMetadata,
  joinLines,
  normalizeStructuredCv,
  parseStructuredCvJson,
  splitLines,
  StructuredCvFieldMetadata,
  StructuredCvProfile,
} from "../profileCv";
import { JobApplication } from "../types";


type CvSectionOption = "" | "Professional Summary" | "Core Skills" | "Experience Highlights" | "Selected Achievements" | "Projects";
type CvSectionStyle = "ats-minimal" | "harvard" | "auckland" | "edinburgh" | "monarch" | "fjord";

type CvBuilderTone = "Concise and direct" | "Executive and polished" | "Technical and detailed" | "Warm and people-focused";
type CvBuilderLanguage = "English" | "Norwegian" | "Spanish" | "French" | "German";

type ExtractionRun = {
  id: number;
  trigger: string;
  status: string;
  artifactFileName?: string;
  startedAtUtc: string;
  completedAtUtc?: string;
  appliedAtUtc?: string;
  parserVersion: string;
  normalizerVersion: string;
  llmPromptVersion: string;
  errorMessage?: string;
};

type QueuedCvRunResponse = {
  queued: boolean;
  extractionRunId: number;
  status: string;
};

type JobListResponse = {
  items: JobApplication[];
  total: number;
  page: number;
  pageSize: number;
};

type RewriteTemplateOption = {
  id: CvSectionStyle;
  title: string;
  eyebrow: string;
  accent: string;
  blurb: string;
  sampleHeading: string;
  sampleMeta: string;
  sampleBullets: string[];
};

type CvBuilderPreview = {
  templateId: CvSectionStyle;
  html: string;
  suggestedFileName: string;
  fullText: string;
  rewrittenText: string;
  structuredCv: StructuredCvProfile;
  sectionName?: string | null;
  targetRole?: string | null;
  jobApplicationId?: number | null;
};

type PdfCarouselItem = {
  templateId: CvSectionStyle;
  title: string;
  fileName: string;
  pdfUrl?: string;
  status: "loading" | "ready" | "error";
  error?: string;
};

type RewriteRequestPayload = {
  sectionName: string | null;
  style: CvSectionStyle;
  templateId: CvSectionStyle;
  targetRole: string | null;
  jobApplicationId: number | null;
  sourceText: string | null;
  promptBackground: string | null;
  tone: string | null;
  language: string | null;
};

type MeResponse = {
  provider?: "local" | "google" | "external";
  id?: string;
  email?: string;
  userName?: string;
  firstName?: string;
  lastName?: string;
  displayName?: string;
  profileCvText?: string;
  profileCvStructureJson?: string;
  avatarImageDataUrl?: string;
  roles?: string[];
  googleLink?: {
    linked: boolean;
    email?: string | null;
    linkedAt?: string | null;
  } | null;
};

const CV_UPLOAD_ACCEPT = ".pdf,.docx,.txt,.md,image/png,image/jpeg,image/webp,application/pdf,application/vnd.openxmlformats-officedocument.wordprocessingml.document,text/plain,text/markdown";
const AVATAR_UPLOAD_ACCEPT = "image/png,image/jpeg,image/webp";
const REWRITE_TEMPLATES: RewriteTemplateOption[] = [
  {
    id: "ats-minimal",
    title: "ATS Minimal",
    eyebrow: "Scanner-friendly",
    accent: "#0f172a",
    blurb: "Compact, direct, and easy for screening systems to parse.",
    sampleHeading: "Senior Backend Engineer",
    sampleMeta: "Acme Systems · Oslo · 2021 - Present",
    sampleBullets: ["Built API workflows with measurable delivery outcomes.", "Kept skills and achievements easy to scan."]
  },
  {
    id: "harvard",
    title: "Harvard",
    eyebrow: "Traditional",
    accent: "#7f1d1d",
    blurb: "Formal hierarchy and restrained tone for conservative hiring flows.",
    sampleHeading: "Professional Summary",
    sampleMeta: "Clear structure · precise dates · credible language",
    sampleBullets: ["Emphasizes polished summaries.", "Works well for broad professional roles."]
  },
  {
    id: "auckland",
    title: "Auckland",
    eyebrow: "Modern sidebar",
    accent: "#0f766e",
    blurb: "Sharper highlights with a more contemporary, design-forward rhythm.",
    sampleHeading: "Selected Impact",
    sampleMeta: "Focused strengths · compact highlights",
    sampleBullets: ["Pulls skills into stronger highlight clusters.", "Good when you want a fresher feel."]
  },
  {
    id: "edinburgh",
    title: "Edinburgh",
    eyebrow: "Editorial",
    accent: "#5b21b6",
    blurb: "More personality and stronger section contrast without losing clarity.",
    sampleHeading: "Experience Highlights",
    sampleMeta: "Premium spacing · stronger visual voice",
    sampleBullets: ["Useful when the CV should feel more distinctive.", "Still keeps wording grounded and factual."]
  },
  {
    id: "monarch",
    title: "Monarch",
    eyebrow: "Executive",
    accent: "#7c2d12",
    blurb: "High-contrast premium presentation for leadership-heavy applications.",
    sampleHeading: "Executive Profile",
    sampleMeta: "Leadership clarity · premium hierarchy",
    sampleBullets: ["Adds more top-level summary emphasis.", "Well suited to senior strategic roles."]
  },
  {
    id: "fjord",
    title: "Fjord",
    eyebrow: "Technical",
    accent: "#0f4c5c",
    blurb: "Calm, high-density layout for engineering resumes and project-heavy CVs.",
    sampleHeading: "Projects & Systems",
    sampleMeta: "Technical depth · practical readability",
    sampleBullets: ["Gives projects and skills more weight.", "Better for technical detail without chaos."]
  },
];

function initialsFrom(values: Array<string | undefined>) {
  const joined = values.map((x) => (x ?? "").trim()).filter(Boolean);
  if (joined.length === 0) return "?";
  if (joined.length === 1) {
    const parts = joined[0].split(/[\s@._-]+/).filter(Boolean);
    if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
    return (parts[0][0] + parts[1][0]).toUpperCase();
  }
  return (joined[0][0] + joined[1][0]).toUpperCase();
}

function confidenceTone(confidence?: number) {
  if (typeof confidence !== "number") return { label: "Review", color: "default" as const };
  if (confidence >= 0.8) return { label: `High ${Math.round(confidence * 100)}%`, color: "success" as const };
  if (confidence >= 0.65) return { label: `Medium ${Math.round(confidence * 100)}%`, color: "warning" as const };
  return { label: `Low ${Math.round(confidence * 100)}%`, color: "error" as const };
}

function FieldReviewNote({ metadata }: { metadata?: StructuredCvFieldMetadata }) {
  if (!metadata) return null;
  const tone = confidenceTone(metadata.confidence);
  return (
    <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", mt: 0.75, alignItems: "center" }}>
      <Chip size="small" color={tone.color} variant={tone.color === "default" ? "outlined" : "filled"} label={tone.label} />
      {metadata.method ? <Chip size="small" variant="outlined" label={metadata.method} /> : null}
      {metadata.sourceBlockId ? <Chip size="small" variant="outlined" label={metadata.sourceBlockId} /> : null}
      {metadata.reviewState ? <Chip size="small" variant="outlined" label={metadata.reviewState} /> : null}
      {metadata.sourceSnippet ? (
        <Typography variant="caption" sx={{ color: "text.secondary" }}>
          {metadata.sourceSnippet}
        </Typography>
      ) : null}
    </Box>
  );
}

// careerOnly splits the two Phase 2 surfaces this component still backs:
//   false -> /profile: account identity + security + preferences
//   true  -> /career:  the master career profile (source of truth)
// Fully separating this into two components is roadmap 2.2; for now the fork keeps each route's
// content — and its Save payload — cleanly scoped.
export default function ProfilePage({
  careerOnly = false,
  onMasterCvAvailabilityChange,
}: {
  careerOnly?: boolean;
  onMasterCvAvailabilityChange?: (hasMasterCv: boolean) => void;
}) {
  const { toast } = useToast();
  const { t } = useI18n();
  const cvInputRef = useRef<HTMLInputElement | null>(null);
  const avatarInputRef = useRef<HTMLInputElement | null>(null);
  const [me, setMe] = useState<MeResponse | null>(null);
  const [loading, setLoading] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);
  const [uploadingCv, setUploadingCv] = useState(false);
  const [improvingCv, setImprovingCv] = useState(false);
  const [rebuildingCv, setRebuildingCv] = useState(false);
  const [uploadingAvatar, setUploadingAvatar] = useState(false);
  const [avatarFile, setAvatarFile] = useState<File | null>(null);
  const [cropOpen, setCropOpen] = useState(false);

  const [email, setEmail] = useState("");
  const [userName, setUserName] = useState("");
  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [displayName, setDisplayName] = useState("");
  const [headline, setHeadline] = useState("");
  const [profileCvText, setProfileCvText] = useState("");
  const [rewritingSection, setRewritingSection] = useState(false);
  const [cvSection, setCvSection] = useState<CvSectionOption>("");
  const [cvSectionStyle, setCvSectionStyle] = useState<CvSectionStyle>("ats-minimal");
  const [cvSectionTargetRole, setCvSectionTargetRole] = useState("");
  const [cvPromptBackground, setCvPromptBackground] = useState("");
  const [cvTone, setCvTone] = useState<CvBuilderTone>("Concise and direct");
  const [cvLanguage, setCvLanguage] = useState<CvBuilderLanguage>("English");
  const [selectedRewriteJobId, setSelectedRewriteJobId] = useState<string>("");
  const [rewritePreview, setRewritePreview] = useState<CvBuilderPreview | null>(null);
  const [rewritePreviewTemplate, setRewritePreviewTemplate] = useState<RewriteTemplateOption | null>(null);
  const [pdfCarousel, setPdfCarousel] = useState<PdfCarouselItem[]>([]);
  const [activePdfIndex, setActivePdfIndex] = useState(0);
  const [buildingPdfDeck, setBuildingPdfDeck] = useState(false);
  const [downloadingPdf, setDownloadingPdf] = useState(false);
  const [savedJobs, setSavedJobs] = useState<JobApplication[]>([]);
  const [parsingCvSections, setParsingCvSections] = useState(false);
  const [reprocessingCv, setReprocessingCv] = useState(false);
  const [structuredCv, setStructuredCv] = useState<StructuredCvProfile>(emptyStructuredCv());
  const [extractionRuns, setExtractionRuns] = useState<ExtractionRun[]>([]);
  const runStatusRef = useRef<Record<number, string>>({});
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");

  // Keep a ref to the latest carousel so the unmount cleanup can revoke the
  // outstanding preview object URLs without re-running on every change.
  const pdfCarouselRef = useRef<PdfCarouselItem[]>([]);
  useEffect(() => {
    pdfCarouselRef.current = pdfCarousel;
  }, [pdfCarousel]);

  useEffect(() => {
    // Revoke any remaining preview object URLs only on unmount. Per-change
    // revocation is already handled explicitly in savePdfToCarousel (replace) and
    // resetPdfCarousel (clear); doing it here on every pdfCarousel change revoked
    // URLs that were still referenced by other items in the deck, breaking their
    // previews.
    return () => {
      pdfCarouselRef.current.forEach((item) => {
        if (item.pdfUrl) {
          window.URL.revokeObjectURL(item.pdfUrl);
        }
      });
    };
  }, []);

  const loadProfile = useCallback(async () => {
    setLoading(true);
    try {
      const [profileResponse, runsResponse, jobsResponse] = await Promise.all([
        api.get<MeResponse>("/auth/me"),
        api.get<ExtractionRun[]>("/profile-cv/runs").catch(() => ({ data: [] as ExtractionRun[] } as any)),
        api.get<JobListResponse>("/jobapplications", { params: { page: 1, pageSize: 100, sortBy: "dateApplied", sortDir: "desc" } }).catch(() => ({ data: { items: [], total: 0, page: 1, pageSize: 100 } } as any)),
      ]);
      const r = profileResponse;
      setMe(r.data);
      setEmail(r.data?.email ?? "");
      setUserName(r.data?.userName ?? "");
      setFirstName(r.data?.firstName ?? "");
      setLastName(r.data?.lastName ?? "");
      setDisplayName(r.data?.displayName ?? "");
      setProfileCvText(r.data?.profileCvText ?? "");
      setStructuredCv(parseStructuredCvJson(r.data?.profileCvStructureJson));
      setExtractionRuns(runsResponse.data ?? []);
      setSavedJobs(jobsResponse.data?.items ?? []);
      setHeadline(window.localStorage.getItem("profileHeadline") ?? "");
      setLoadError(null);
    } catch (error: any) {
      setMe(null);
      setExtractionRuns([]);
      setSavedJobs([]);
      setLoadError(String(error?.response?.data || error?.message || "Unable to load profile right now."));
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadProfile();
  }, [loadProfile]);

  useEffect(() => {
    const activeRuns = extractionRuns.filter((run) => run.status === "queued" || run.status === "running");
    if (activeRuns.length === 0) return;

    const timer = window.setInterval(() => {
      void loadProfile();
    }, 4000);

    return () => window.clearInterval(timer);
  }, [extractionRuns, loadProfile]);

  useEffect(() => {
    const previous = runStatusRef.current;
    for (const run of extractionRuns) {
      const prior = previous[run.id];
      if ((prior === "queued" || prior === "running") && run.status === "applied") {
        toast(`CV ${run.trigger} completed.`, "success");
      }
      if ((prior === "queued" || prior === "running") && run.status === "failed") {
        toast(run.errorMessage || `CV ${run.trigger} failed.`, "error");
      }
      previous[run.id] = run.status;
    }
  }, [extractionRuns, toast]);

  const initials = useMemo(() => initialsFrom([me?.displayName, me?.firstName, me?.lastName, me?.userName, me?.email]), [me]);
  const isLocal = me?.provider === "local";
  const fullName = [me?.firstName, me?.lastName].filter(Boolean).join(" ");
  const cvWordCount = profileCvText.trim() ? profileCvText.trim().split(/\s+/).length : 0;

  const providerLabel = me?.provider === "local" ? t("profileLocalAccount") : me?.provider === "google" ? t("profileGoogleSession") : t("profileExternalSession");
  const googleLabel = me?.googleLink?.linked
    ? me.googleLink.email
      ? t("profileGoogleLinkedWithEmail", { email: me.googleLink.email })
      : t("profileGoogleLinked")
    : t("profileGoogleNotLinked");
  const cvLabel = profileCvText.trim() ? t("profileCvReady", { count: cvWordCount }) : t("profileCvMissing");
  const latestRun = extractionRuns[0];
  const selectedRewriteTemplate = REWRITE_TEMPLATES.find((option) => option.id === cvSectionStyle) ?? REWRITE_TEMPLATES[0];
  const selectedRewriteJob = savedJobs.find((job) => String(job.id) === selectedRewriteJobId) ?? null;
  const rewriteReady = Boolean(rewritePreview?.html && rewritePreview.fullText.trim());
  const activePdfItem = pdfCarousel[activePdfIndex] ?? null;

  const releasePdfCarousel = useCallback((items: PdfCarouselItem[]) => {
    items.forEach((item) => {
      if (item.pdfUrl) {
        window.URL.revokeObjectURL(item.pdfUrl);
      }
    });
  }, []);

  const buildRewritePayload = useCallback((templateId: CvSectionStyle): RewriteRequestPayload => ({
    sectionName: cvSection || null,
    style: templateId,
    templateId,
    targetRole: cvSectionTargetRole.trim() || null,
    jobApplicationId: selectedRewriteJob ? selectedRewriteJob.id : null,
    sourceText: profileCvText.trim() || null,
    promptBackground: cvPromptBackground.trim() || null,
    tone: cvTone,
    language: cvLanguage,
  }), [cvLanguage, cvPromptBackground, cvSection, cvSectionTargetRole, cvTone, profileCvText, selectedRewriteJob]);

  const resetPdfCarousel = useCallback(() => {
    setPdfCarousel((current) => {
      releasePdfCarousel(current);
      return [];
    });
    setActivePdfIndex(0);
  }, [releasePdfCarousel]);

  const savePdfToCarousel = useCallback(async (templateId: CvSectionStyle, download = false) => {
    const template = REWRITE_TEMPLATES.find((option) => option.id === templateId) ?? REWRITE_TEMPLATES[0];
    const payload = buildRewritePayload(templateId);
    const response = await api.post("/profile-cv/export-pdf", payload, { responseType: "blob" });
    const blob = new Blob([response.data], { type: "application/pdf" });
    const url = window.URL.createObjectURL(blob);
    const item: PdfCarouselItem = {
      templateId,
      title: template.title,
      fileName: rewritePreview?.suggestedFileName || `${templateId}-cv.pdf`,
      pdfUrl: url,
      status: "ready",
    };

    setPdfCarousel((current) => {
      const existing = current.find((entry) => entry.templateId === templateId);
      if (existing?.pdfUrl) {
        window.URL.revokeObjectURL(existing.pdfUrl);
      }
      const next = existing
        ? current.map((entry) => (entry.templateId === templateId ? item : entry))
        : [...current, item];
      setActivePdfIndex(next.findIndex((entry) => entry.templateId === templateId));
      return next;
    });

    if (download) {
      const link = document.createElement("a");
      link.href = url;
      link.download = item.fileName;
      document.body.appendChild(link);
      link.click();
      link.remove();
    }

    return item;
  }, [buildRewritePayload, rewritePreview?.suggestedFileName]);

  const buildPdfCarousel = useCallback(async () => {
    setBuildingPdfDeck(true);
    resetPdfCarousel();
    const orderedTemplates = [selectedRewriteTemplate.id, ...REWRITE_TEMPLATES.map((option) => option.id).filter((id) => id !== selectedRewriteTemplate.id)];
    const seedItems = orderedTemplates.map((templateId) => ({
      templateId,
      title: REWRITE_TEMPLATES.find((option) => option.id === templateId)?.title ?? templateId,
      fileName: `${templateId}-cv.pdf`,
      status: "loading" as const,
    }));
    setPdfCarousel(seedItems);
    setActivePdfIndex(0);

    for (const templateId of orderedTemplates) {
      try {
        const item = await savePdfToCarousel(templateId, false);
        setPdfCarousel((current) => current.map((entry) => entry.templateId === templateId ? item : entry));
      } catch (error: any) {
        const message = getApiErrorMessage(error, `Failed to generate the ${templateId} PDF preview.`);
        setPdfCarousel((current) => current.map((entry) => entry.templateId === templateId ? { ...entry, status: "error", error: message } : entry));
      }
    }

    setBuildingPdfDeck(false);
  }, [resetPdfCarousel, savePdfToCarousel, selectedRewriteTemplate.id]);

  useEffect(() => {
    resetPdfCarousel();
  }, [rewritePreview?.fullText, rewritePreview?.templateId, rewritePreview?.targetRole, resetPdfCarousel]);

  return (
    <Paper sx={{ mt: 0, p: 2.5, 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)" }}>
      <CropImageDialog
        open={cropOpen}
        file={avatarFile}
        onClose={() => {
          setCropOpen(false);
          setAvatarFile(null);
        }}
        onSave={async (blob) => {
          const file = new File([blob], "avatar.png", { type: "image/png" });
          const formData = new FormData();
          formData.append("file", file);
          setUploadingAvatar(true);
          try {
            const response = await api.post<{ avatarImageDataUrl?: string }>("/auth/avatar", formData, {
              headers: { "Content-Type": "multipart/form-data" },
            });
            setMe((prev) => (prev ? { ...prev, avatarImageDataUrl: response.data?.avatarImageDataUrl ?? prev.avatarImageDataUrl } : prev));
            setCropOpen(false);
            setAvatarFile(null);
            toast(t("profileImageUpdated"), "success");
          } catch (e: any) {
            toast(String(e?.response?.data || e?.message || t("profileImageUploadFailed")), "error");
          } finally {
            setUploadingAvatar(false);
          }
        }}
      />

      {loadError ? (
        <Alert severity="error" sx={{ mb: 2, borderRadius: 2.5 }} action={<Button color="inherit" size="small" onClick={() => void loadProfile()}>Retry</Button>}>
          Unable to load profile.
          <Typography variant="body2" sx={{ mt: 0.5 }}>{loadError}</Typography>
        </Alert>
      ) : null}

      <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, flexWrap: "wrap" }}>
        <Box sx={{ display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap" }}>
          <Box sx={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 1 }}>
            <Avatar src={me?.avatarImageDataUrl || undefined} sx={{ width: 84, height: 84, fontWeight: 900, fontSize: 28 }}>{initials}</Avatar>
            <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", justifyContent: "center" }}>
              <input
                ref={avatarInputRef}
                type="file"
                accept={AVATAR_UPLOAD_ACCEPT}
                style={{ display: "none" }}
                onChange={(event) => {
                  const file = event.target.files?.[0] ?? null;
                  event.target.value = "";
                  if (!file) return;
                  setAvatarFile(file);
                  setCropOpen(true);
                }}
              />
              <Button variant="outlined" size="small" startIcon={<PhotoCameraOutlinedIcon />} disabled={!isLocal || uploadingAvatar} onClick={() => avatarInputRef.current?.click()}>
                {uploadingAvatar ? t("profileUploading") : t("profileChangeImage")}
              </Button>
              {me?.avatarImageDataUrl ? (
                <Button
                  variant="text"
                  size="small"
                  color="inherit"
                  startIcon={<DeleteOutlineIcon />}
                  disabled={!isLocal || uploadingAvatar}
                  onClick={async () => {
                    setUploadingAvatar(true);
                    try {
                      await api.delete("/auth/avatar");
                      setMe((prev) => (prev ? { ...prev, avatarImageDataUrl: undefined } : prev));
                      toast(t("profileImageRemoved"), "success");
                    } catch (e: any) {
                      toast(String(e?.response?.data || e?.message || t("profileImageRemoveFailed")), "error");
                    } finally {
                      setUploadingAvatar(false);
                    }
                  }}
                >
                  {t("profileRemoveImage")}
                </Button>
              ) : null}
            </Box>
          </Box>
          <Box>
            <Typography variant="h5" sx={{ fontWeight: 900 }}>
              {careerOnly ? "Master career profile" : t("profileTitle")}
            </Typography>
            <Typography sx={{ color: "text.secondary" }}>{me?.userName || me?.displayName || fullName || me?.email || "-"}</Typography>
            <Typography variant="body2" sx={{ color: "text.secondary" }}>{headline || t("profileHeadlinePlaceholder")}</Typography>
          </Box>
        </Box>
        <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", alignItems: "flex-start" }}>
          <Chip label={providerLabel} color={me?.provider === "local" ? "primary" : "default"} />
          <Chip label={googleLabel} color={me?.googleLink?.linked ? "success" : "default"} variant={me?.googleLink?.linked ? "filled" : "outlined"} />
          <Chip label={cvLabel} color={profileCvText.trim() ? "success" : "warning"} variant={profileCvText.trim() ? "filled" : "outlined"} />
        </Box>
      </Box>

      {!careerOnly ? <>
        <AuthStatusCard />
        <GoogleAuthCard />
        <MicrosoftAuthCard />
      </> : null}

      <Box sx={{ mt: 3, display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 2 }}>
        {!careerOnly ? <Box sx={{ gridColumn: "1 / -1" }}>
          <Typography variant="h6">{t("profileAccountSection")}</Typography>
          {!isLocal ? (
            <Alert severity="info" sx={{ mt: 1 }}>
              {t("profileReadOnlyInfo")}
            </Alert>
          ) : null}
        </Box> : null}

        {!careerOnly ? <>
          <TextField label={t("profileDisplayName")} value={displayName} onChange={(e) => setDisplayName(e.target.value)} disabled={!isLocal} fullWidth />
          <TextField label={t("profileUsername")} value={userName} onChange={(e) => setUserName(e.target.value)} disabled={!isLocal} fullWidth />
          <TextField label={t("profileFirstName")} value={firstName} onChange={(e) => setFirstName(e.target.value)} disabled={!isLocal} fullWidth />
          <TextField label={t("profileLastName")} value={lastName} onChange={(e) => setLastName(e.target.value)} disabled={!isLocal} fullWidth />
          <TextField label={t("profileEmail")} value={email} onChange={(e) => setEmail(e.target.value)} disabled={!isLocal} fullWidth />
          <TextField
          label={t("profileHeadline")}
          value={headline}
          onChange={(e) => setHeadline(e.target.value)}
          helperText={t("profileHeadlineHelp")}
          fullWidth
          />
        </> : null}

        <Box sx={{ gridColumn: "1 / -1", p: 2, borderRadius: 3, border: "1px solid", borderColor: "divider", backgroundColor: "background.default", display: careerOnly ? "block" : "none" }}>
          <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, flexWrap: "wrap", alignItems: "center", mb: 1.5 }}>
            <Box>
              <Typography variant="h6">{t("profileMasterCv")}</Typography>
              <Typography variant="body2" sx={{ color: "text.secondary" }}>
                {t("profileMasterCvBody")}
              </Typography>
            </Box>
            <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
              <input
                ref={cvInputRef}
                type="file"
                accept={CV_UPLOAD_ACCEPT}
                style={{ display: "none" }}
                onChange={async (event) => {
                  const file = event.target.files?.[0];
                  event.target.value = "";
                  if (!file) return;
                  const formData = new FormData();
                  formData.append("file", file);
                  setUploadingCv(true);
                  try {
                    await api.post<QueuedCvRunResponse>("/profile-cv/upload", formData, { headers: { "Content-Type": "multipart/form-data" } });
                    await loadProfile();
                    toast(t("profileCvUploaded"), "success");
                  } catch (e: any) {
                    toast(String(e?.response?.data || e?.message || t("profileCvUploadFailed")), "error");
                  } finally {
                    setUploadingCv(false);
                  }
                }}
              />
              <Button variant="outlined" disabled={!isLocal || uploadingCv || improvingCv || rebuildingCv} onClick={() => cvInputRef.current?.click()}>
                {uploadingCv ? t("profileUploading") : t("profileUploadCv")}
              </Button>
              <Button
                variant="outlined"
                disabled={!isLocal || !profileCvText.trim() || uploadingCv || improvingCv || rebuildingCv}
                onClick={async () => {
                  setRebuildingCv(true);
                  try {
                    const res = await api.post<QueuedCvRunResponse>("/profile-cv/rebuild");
                    await loadProfile();
                    toast(`Queued CV rebuild (run ${res.data.extractionRunId}).`, "info");
                  } catch (e: any) {
                    toast(String(e?.response?.data || e?.message || t("profileCvRebuildFailed")), "error");
                  } finally {
                    setRebuildingCv(false);
                  }
                }}
              >
                {rebuildingCv ? t("profileCvRebuilding") : t("profileCvRebuild")}
              </Button>
              <Button
                variant="outlined"
                disabled={!isLocal || !profileCvText.trim() || uploadingCv || improvingCv || rebuildingCv}
                onClick={async () => {
                  setImprovingCv(true);
                  try {
                    const res = await api.post<QueuedCvRunResponse>("/profile-cv/improve");
                    await loadProfile();
                    toast(`Queued CV improve run (run ${res.data.extractionRunId}).`, "info");
                  } catch (e: any) {
                    toast(String(e?.response?.data || e?.message || t("profileCvImproveFailed")), "error");
                  } finally {
                    setImprovingCv(false);
                  }
                }}
              >
                {improvingCv ? t("profileCvImproving") : t("profileCvImprove")}
              </Button>
              <Button
                variant="outlined"
                disabled={!isLocal || uploadingCv || improvingCv || rebuildingCv || reprocessingCv || !latestRun}
                onClick={async () => {
                  setReprocessingCv(true);
                  try {
                    const res = await api.post<QueuedCvRunResponse>("/profile-cv/reprocess");
                    await loadProfile();
                    toast(`Queued CV reprocess run (run ${res.data.extractionRunId}).`, "info");
                  } catch (e: any) {
                    toast(String(e?.response?.data || e?.message || t("profileCvReprocessFailed")), "error");
                  } finally {
                    setReprocessingCv(false);
                  }
                }}
              >
                {reprocessingCv ? t("profileCvReprocessing") : t("profileCvReprocess")}
              </Button>
            </Box>
          </Box>
          {uploadingCv ? <LinearProgress sx={{ mb: 1.5 }} /> : null}
          <Alert severity="info" sx={{ mb: 2, borderRadius: 2.5 }}>
            {t("profileCvStructuredDefaultHint")}
          </Alert>
          <Accordion disableGutters elevation={0} sx={{ mb: 2, borderRadius: 3, border: "1px solid", borderColor: "divider", backgroundColor: "background.paper", "&:before": { display: "none" } }}>
            <AccordionSummary expandIcon={<ExpandMoreIcon />}>
              <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1.5, alignItems: "center", width: "100%", pr: 1 }}>
                <Box>
                  <Typography variant="subtitle1" sx={{ fontWeight: 800 }}>{t("profileCvRawPanelTitle")}</Typography>
                  <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvRawPanelHelp")}</Typography>
                </Box>
                <Chip size="small" label={t("profileCvSectionWordCount", { count: cvWordCount })} />
              </Box>
            </AccordionSummary>
            <AccordionDetails>
              <TextField
                label={t("profileCvTextLabel")}
                value={profileCvText}
                onChange={(e) => setProfileCvText(e.target.value)}
                helperText={t("profileCvTextHelp")}
                multiline
                minRows={12}
                disabled={!isLocal}
                fullWidth
              />
              <Box sx={{ mt: 1.5, display: "flex", justifyContent: "flex-end" }}>
                <Button variant="text" disabled={!profileCvText.trim()} onClick={() => navigator.clipboard.writeText(profileCvText)}>
                  {t("profileCopyCvText")}
                </Button>
              </Box>
            </AccordionDetails>
          </Accordion>
          <Box sx={{ mt: 2, p: 1.5, borderRadius: 3, border: "1px solid", borderColor: "divider", backgroundColor: "background.paper" }}>
            <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, flexWrap: "wrap", alignItems: "center", mb: 1.5 }}>
              <Box>
                <Typography variant="subtitle1" sx={{ fontWeight: 800 }}>{t("profileCvExtractionHistory")}</Typography>
                <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvExtractionHistoryHelp")}</Typography>
              </Box>
              {structuredCv.metadata.profileVersion ? <Chip label={t("profileCvProfileVersion", { count: structuredCv.metadata.profileVersion })} size="small" /> : null}
            </Box>
            {latestRun ? (
              <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1.25 }}>
                {extractionRuns.map((run) => (
                  <Box key={run.id} sx={{ p: 1.25, borderRadius: 2.5, border: "1px solid", borderColor: run.id === structuredCv.metadata.appliedExtractionRunId ? "primary.main" : "divider", backgroundColor: "background.default" }}>
                    <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1, flexWrap: "wrap", alignItems: "center", mb: 0.75 }}>
                      <Typography variant="overline">{run.trigger}</Typography>
                      <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap" }}>
                        <Chip size="small" label={run.status} color={run.status === "applied" ? "success" : run.status === "failed" ? "error" : "default"} variant={run.status === "applied" ? "filled" : "outlined"} />
                        {run.id === structuredCv.metadata.appliedExtractionRunId ? <Chip size="small" color="primary" label={t("profileCvCurrentRun")} /> : null}
                      </Box>
                    </Box>
                    <Typography variant="body2" sx={{ color: "text.secondary" }}>{run.artifactFileName || t("profileCvNoStoredArtifact")}</Typography>
                    <Typography variant="caption" sx={{ color: "text.secondary", display: "block", mt: 0.75 }}>
                      {run.parserVersion} · {new Date(run.startedAtUtc).toLocaleString()}
                    </Typography>
                    {run.errorMessage ? (
                      <Typography variant="caption" sx={{ color: "error.main", display: "block", mt: 0.75 }}>
                        {run.errorMessage}
                      </Typography>
                    ) : null}
                  </Box>
                ))}
              </Box>
            ) : (
              <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvExtractionHistoryEmpty")}</Typography>
            )}
          </Box>
          <Box sx={{ mt: 2, p: 1.5, borderRadius: 3, border: "1px solid", borderColor: "divider", backgroundColor: "background.paper" }}>
            <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, flexWrap: "wrap", alignItems: "center", mb: 1.5 }}>
              <Box>
                <Typography variant="subtitle1" sx={{ fontWeight: 800 }}>{t("profileCvStructureOverview")}</Typography>
                <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvStructureOverviewHelp")}</Typography>
              </Box>
              <Button
                variant="outlined"
                disabled={!isLocal || !profileCvText.trim() || parsingCvSections}
                onClick={async () => {
                  setParsingCvSections(true);
                  try {
                    const res = await api.post<{ structuredCv?: StructuredCvProfile }>("/profile-cv/parse", { text: profileCvText });
                    setStructuredCv(normalizeStructuredCv(res.data?.structuredCv));
                    toast(t("profileCvStructureParsed"), "success");
                  } catch (e: any) {
                    toast(String(e?.response?.data || e?.message || t("profileCvStructureParseFailed")), "error");
                  } finally {
                    setParsingCvSections(false);
                  }
                }}
              >
                {parsingCvSections ? t("profileCvStructureParsing") : t("profileCvStructureParse")}
              </Button>
            </Box>
            {structuredCv.sections.length > 0 ? (
              <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1.5 }}>
                {structuredCv.sections.map((section) => {
                  const safeContent = typeof section.content === "string" ? section.content : "";
                  const safeWordCount = Number.isFinite(Number(section.wordCount)) ? Number(section.wordCount) : (safeContent.trim() ? safeContent.trim().split(/\s+/).length : 0);
                  return (
                    <Box key={section.name} sx={{ p: 1.25, borderRadius: 2.5, border: "1px solid", borderColor: "divider", backgroundColor: "background.default" }}>
                      <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1, alignItems: "center", mb: 0.75 }}>
                        <Typography variant="overline">{section.name}</Typography>
                        <Chip size="small" label={t("profileCvSectionWordCount", { count: safeWordCount })} />
                      </Box>
                      <Typography variant="body2" sx={{ color: "text.secondary", whiteSpace: "pre-wrap" }}>{safeContent.slice(0, 280)}{safeContent.length > 280 ? "…" : ""}</Typography>
                    </Box>
                  );
                })}
              </Box>
            ) : (
              <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvStructureEmpty")}</Typography>
            )}
          </Box>
          <Box sx={{ mt: 2, p: 1.5, borderRadius: 3, border: "1px solid", borderColor: "divider", backgroundColor: "background.paper" }}>
            <Box sx={{ mb: 1.5 }}>
              <Typography variant="subtitle1" sx={{ fontWeight: 800 }}>{t("profileCvStructuredEditor")}</Typography>
              <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvStructuredEditorHelp")}</Typography>
            </Box>

            <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1.5 }}>
              <Box>
                <TextField label={t("profileCvContactFullName")} value={structuredCv.contact.fullName ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, contact: { ...prev.contact, fullName: e.target.value || undefined } }))} fullWidth />
                <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "contact.fullName")} />
              </Box>
              <Box>
                <TextField label={t("profileCvContactHeadline")} value={structuredCv.contact.headline ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, contact: { ...prev.contact, headline: e.target.value || undefined } }))} fullWidth />
                <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "contact.headline")} />
              </Box>
              <Box>
                <TextField label={t("profileCvContactEmail")} value={structuredCv.contact.email ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, contact: { ...prev.contact, email: e.target.value || undefined } }))} fullWidth />
                <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "contact.email")} />
              </Box>
              <Box>
                <TextField label={t("profileCvContactPhone")} value={structuredCv.contact.phone ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, contact: { ...prev.contact, phone: e.target.value || undefined } }))} fullWidth />
                <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "contact.phone")} />
              </Box>
              <Box>
                <TextField label={t("profileCvContactLocation")} value={structuredCv.contact.location ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, contact: { ...prev.contact, location: e.target.value || undefined } }))} fullWidth />
                <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "contact.location")} />
              </Box>
              <TextField label={t("profileCvContactWebsite")} value={structuredCv.contact.website ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, contact: { ...prev.contact, website: e.target.value || undefined } }))} fullWidth />
              <TextField label={t("profileCvContactLinkedIn")} value={structuredCv.contact.linkedIn ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, contact: { ...prev.contact, linkedIn: e.target.value || undefined } }))} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} />
            </Box>

            <Box sx={{ mt: 2, display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1.5 }}>
              <Box>
                <TextField
                  label={t("profileCvStructuredSummary")}
                  value={joinLines(structuredCv.summary)}
                  onChange={(e) => setStructuredCv((prev) => ({ ...prev, summary: splitLines(e.target.value) }))}
                  helperText={t("profileCvStructuredListHelp")}
                  multiline
                  minRows={5}
                  fullWidth
                />
                <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "summary")} />
              </Box>
              <Box>
                <TextField
                  label={t("profileCvStructuredSkills")}
                  value={joinLines(structuredCv.skills)}
                  onChange={(e) => setStructuredCv((prev) => ({ ...prev, skills: splitLines(e.target.value) }))}
                  helperText={t("profileCvStructuredListHelp")}
                  multiline
                  minRows={5}
                  fullWidth
                />
                <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "skills")} />
              </Box>
              <Box>
                <TextField
                  label={t("profileCvStructuredInterests")}
                  value={joinLines(structuredCv.interests)}
                  onChange={(e) => setStructuredCv((prev) => ({ ...prev, interests: splitLines(e.target.value) }))}
                  helperText={t("profileCvStructuredListHelp")}
                  multiline
                  minRows={4}
                  fullWidth
                />
                <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "interests")} />
              </Box>
            </Box>

            <Box sx={{ mt: 2 }}>
              <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1, alignItems: "center", mb: 1 }}>
                <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>{t("profileCvStructuredLanguages")}</Typography>
                <Button variant="outlined" size="small" onClick={() => setStructuredCv((prev) => ({ ...prev, languages: [...prev.languages, { name: "", level: "", notes: "" }] }))}>{t("profileCvStructuredAddLanguage")}</Button>
              </Box>
              <FieldReviewNote metadata={getStructuredCvFieldMetadata(structuredCv, "languages")} />
              {structuredCv.languages.length === 0 ? <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvStructuredEmpty")}</Typography> : null}
              {structuredCv.languages.map((language, index) => (
                <Box key={`language-${index}`} sx={{ p: 1.25, mb: 1, borderRadius: 2.5, border: "1px solid", borderColor: "divider", backgroundColor: "background.default" }}>
                  <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr 1fr auto" }, gap: 1 }}>
                    <TextField label={t("profileCvLanguageName")} value={language.name ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, languages: prev.languages.map((entry, entryIndex) => entryIndex === index ? { ...entry, name: e.target.value || undefined } : entry) }))} fullWidth />
                    <TextField label={t("profileCvLanguageLevel")} value={language.level ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, languages: prev.languages.map((entry, entryIndex) => entryIndex === index ? { ...entry, level: e.target.value || undefined } : entry) }))} fullWidth />
                    <TextField label={t("profileCvLanguageNotes")} value={language.notes ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, languages: prev.languages.map((entry, entryIndex) => entryIndex === index ? { ...entry, notes: e.target.value || undefined } : entry) }))} fullWidth />
                    <Button color="inherit" onClick={() => setStructuredCv((prev) => ({ ...prev, languages: prev.languages.filter((_, entryIndex) => entryIndex !== index) }))}>{t("profileCvStructuredRemove")}</Button>
                  </Box>
                </Box>
              ))}
            </Box>

            <Box sx={{ mt: 2 }}>
              <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1, alignItems: "center", mb: 1 }}>
                <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>{t("profileCvStructuredJobs")}</Typography>
                <Button variant="outlined" size="small" onClick={() => setStructuredCv((prev) => ({ ...prev, jobs: [...prev.jobs, { title: "", company: "", location: "", start: "", end: "", isCurrent: false, bullets: [], skills: [] }] }))}>{t("profileCvStructuredAddJob")}</Button>
              </Box>
              {structuredCv.jobs.length === 0 ? <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvStructuredEmpty")}</Typography> : null}
              {structuredCv.jobs.map((job, index) => (
                <Box key={`job-${index}`} sx={{ p: 1.25, mb: 1, borderRadius: 2.5, border: "1px solid", borderColor: "divider", backgroundColor: "background.default" }}>
                  <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1 }}>
                    <TextField label={t("profileCvJobTitle")} value={job.title ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, jobs: prev.jobs.map((entry, entryIndex) => entryIndex === index ? { ...entry, title: e.target.value || undefined } : entry) }))} fullWidth />
                    <TextField label={t("profileCvJobCompany")} value={job.company ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, jobs: prev.jobs.map((entry, entryIndex) => entryIndex === index ? { ...entry, company: e.target.value || undefined } : entry) }))} fullWidth />
                    <TextField label={t("profileCvJobLocation")} value={job.location ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, jobs: prev.jobs.map((entry, entryIndex) => entryIndex === index ? { ...entry, location: e.target.value || undefined } : entry) }))} fullWidth />
                    <Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 1 }}>
                      <TextField label={t("profileCvJobStart")} value={job.start ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, jobs: prev.jobs.map((entry, entryIndex) => entryIndex === index ? { ...entry, start: e.target.value || undefined } : entry) }))} fullWidth />
                      <TextField label={t("profileCvJobEnd")} value={job.end ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, jobs: prev.jobs.map((entry, entryIndex) => entryIndex === index ? { ...entry, end: e.target.value || undefined, isCurrent: /present|current/i.test(e.target.value) || entry.isCurrent } : entry) }))} fullWidth />
                    </Box>
                    <TextField label={t("profileCvJobBullets")} value={joinLines(job.bullets)} onChange={(e) => setStructuredCv((prev) => ({ ...prev, jobs: prev.jobs.map((entry, entryIndex) => entryIndex === index ? { ...entry, bullets: splitLines(e.target.value) } : entry) }))} helperText={t("profileCvStructuredListHelp")} multiline minRows={5} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} />
                    <TextField label={t("profileCvJobSkills")} value={joinLines(job.skills)} onChange={(e) => setStructuredCv((prev) => ({ ...prev, jobs: prev.jobs.map((entry, entryIndex) => entryIndex === index ? { ...entry, skills: splitLines(e.target.value) } : entry) }))} helperText={t("profileCvStructuredListHelp")} multiline minRows={3} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} />
                    <Box sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" }, display: "flex", justifyContent: "flex-end" }}>
                      <Button color="inherit" onClick={() => setStructuredCv((prev) => ({ ...prev, jobs: prev.jobs.filter((_, entryIndex) => entryIndex !== index) }))}>{t("profileCvStructuredRemove")}</Button>
                    </Box>
                  </Box>
                </Box>
              ))}
            </Box>

            <Box sx={{ mt: 2 }}>
              <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1, alignItems: "center", mb: 1 }}>
                <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>{t("profileCvStructuredEducation")}</Typography>
                <Button variant="outlined" size="small" onClick={() => setStructuredCv((prev) => ({ ...prev, education: [...prev.education, { qualification: "", institution: "", location: "", start: "", end: "", details: [] }] }))}>{t("profileCvStructuredAddEducation")}</Button>
              </Box>
              {structuredCv.education.length === 0 ? <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvStructuredEmpty")}</Typography> : null}
              {structuredCv.education.map((education, index) => (
                <Box key={`education-${index}`} sx={{ p: 1.25, mb: 1, borderRadius: 2.5, border: "1px solid", borderColor: "divider", backgroundColor: "background.default" }}>
                  <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1 }}>
                    <TextField label={t("profileCvEducationQualification")} value={education.qualification ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, education: prev.education.map((entry, entryIndex) => entryIndex === index ? { ...entry, qualification: e.target.value || undefined } : entry) }))} fullWidth />
                    <TextField label={t("profileCvEducationInstitution")} value={education.institution ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, education: prev.education.map((entry, entryIndex) => entryIndex === index ? { ...entry, institution: e.target.value || undefined } : entry) }))} fullWidth />
                    <TextField label={t("profileCvEducationLocation")} value={education.location ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, education: prev.education.map((entry, entryIndex) => entryIndex === index ? { ...entry, location: e.target.value || undefined } : entry) }))} fullWidth />
                    <Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 1 }}>
                      <TextField label={t("profileCvEducationStart")} value={education.start ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, education: prev.education.map((entry, entryIndex) => entryIndex === index ? { ...entry, start: e.target.value || undefined } : entry) }))} fullWidth />
                      <TextField label={t("profileCvEducationEnd")} value={education.end ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, education: prev.education.map((entry, entryIndex) => entryIndex === index ? { ...entry, end: e.target.value || undefined } : entry) }))} fullWidth />
                    </Box>
                    <TextField label={t("profileCvEducationDetails")} value={joinLines(education.details)} onChange={(e) => setStructuredCv((prev) => ({ ...prev, education: prev.education.map((entry, entryIndex) => entryIndex === index ? { ...entry, details: splitLines(e.target.value) } : entry) }))} helperText={t("profileCvStructuredListHelp")} multiline minRows={4} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} />
                    <Box sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" }, display: "flex", justifyContent: "flex-end" }}>
                      <Button color="inherit" onClick={() => setStructuredCv((prev) => ({ ...prev, education: prev.education.filter((_, entryIndex) => entryIndex !== index) }))}>{t("profileCvStructuredRemove")}</Button>
                    </Box>
                  </Box>
                </Box>
              ))}
            </Box>

            <Box sx={{ mt: 2 }}>
              <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1, alignItems: "center", mb: 1 }}>
                <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>{t("profileCvStructuredOtherSections")}</Typography>
                <Button variant="outlined" size="small" onClick={() => setStructuredCv((prev) => ({ ...prev, otherSections: [...prev.otherSections, { title: "", items: [] }] }))}>{t("profileCvStructuredAddOtherSection")}</Button>
              </Box>
              {structuredCv.otherSections.length === 0 ? <Typography variant="body2" sx={{ color: "text.secondary" }}>{t("profileCvStructuredEmpty")}</Typography> : null}
              {structuredCv.otherSections.map((section, index) => (
                <Box key={`other-${index}`} sx={{ p: 1.25, mb: 1, borderRadius: 2.5, border: "1px solid", borderColor: "divider", backgroundColor: "background.default" }}>
                  <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr auto" }, gap: 1 }}>
                    <TextField label={t("profileCvOtherSectionTitle")} value={section.title ?? ""} onChange={(e) => setStructuredCv((prev) => ({ ...prev, otherSections: prev.otherSections.map((entry, entryIndex) => entryIndex === index ? { ...entry, title: e.target.value || undefined } : entry) }))} fullWidth />
                    <Button color="inherit" onClick={() => setStructuredCv((prev) => ({ ...prev, otherSections: prev.otherSections.filter((_, entryIndex) => entryIndex !== index) }))}>{t("profileCvStructuredRemove")}</Button>
                    <TextField label={t("profileCvOtherSectionItems")} value={joinLines(section.items)} onChange={(e) => setStructuredCv((prev) => ({ ...prev, otherSections: prev.otherSections.map((entry, entryIndex) => entryIndex === index ? { ...entry, items: splitLines(e.target.value) } : entry) }))} helperText={t("profileCvStructuredListHelp")} multiline minRows={4} fullWidth sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }} />
                  </Box>
                </Box>
              ))}
            </Box>
          </Box>
          <Box sx={{ mt: 2, p: 2.25, borderRadius: 4, border: "1px solid", borderColor: "divider", background: "linear-gradient(180deg, rgba(15,23,42,0.04) 0%, rgba(15,23,42,0) 100%)" }}>
            <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, flexWrap: "wrap", alignItems: "center", mb: 1.75 }}>
              <Box>
                <Typography variant="subtitle1" sx={{ fontWeight: 900 }}>Template-driven CV builder</Typography>
                <Typography variant="body2" sx={{ color: "text.secondary", maxWidth: 720 }}>
                  Choose a template, optionally target one section, and tailor the output toward a saved job or free-text role target. The preview below renders the actual PDF layout before you apply it.
                </Typography>
              </Box>
              <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", alignItems: "center" }}>
                <Chip size="small" variant="outlined" label={cvSection || "Whole CV rewrite"} />
                {selectedRewriteJob ? <Chip size="small" color="primary" variant="outlined" label={`Saved job · ${selectedRewriteJob.jobTitle}`} /> : null}
                {rewriteReady ? <Chip size="small" color="success" label="Preview ready" /> : null}
              </Box>
            </Box>

            <Box sx={{ mb: 2 }}>
              <Paper sx={{ p: { xs: 1.5, md: 2 }, borderRadius: 4, border: "1px solid", borderColor: "divider", background: `linear-gradient(180deg, ${selectedRewriteTemplate.accent}14 0%, rgba(255,255,255,0.96) 100%)`, boxShadow: "0 18px 40px rgba(15,23,42,0.08)" }}>
                <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", lg: "1.15fr 0.85fr" }, gap: 2, alignItems: "stretch" }}>
                  <Box sx={{ p: { xs: 1.25, md: 2 }, borderRadius: 3.5, background: "rgba(255,255,255,0.82)", border: "1px solid", borderColor: "rgba(15,23,42,0.08)" }}>
                    <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 1.5, mb: 1.5 }}>
                      <Box>
                        <Typography variant="overline" sx={{ color: selectedRewriteTemplate.accent, fontWeight: 900, letterSpacing: '0.16em' }}>{selectedRewriteTemplate.eyebrow}</Typography>
                        <Typography variant="h6" sx={{ fontWeight: 900 }}>{selectedRewriteTemplate.title}</Typography>
                        <Typography variant="body2" sx={{ color: "text.secondary", mt: 0.25, maxWidth: 560 }}>{selectedRewriteTemplate.blurb}</Typography>
                      </Box>
                      <IconButton size="small" onClick={() => setRewritePreviewTemplate(selectedRewriteTemplate)}>
                        <ZoomInOutlinedIcon fontSize="small" />
                      </IconButton>
                    </Box>

                    <Box sx={{ borderRadius: 3.5, overflow: "hidden", border: "1px solid", borderColor: "rgba(15,23,42,0.1)", background: "white", minHeight: { xs: 280, md: 340 }, boxShadow: "inset 0 1px 0 rgba(255,255,255,0.7)" }}>
                      <Box sx={{ px: { xs: 2, md: 3 }, py: { xs: 2, md: 2.5 }, borderBottom: "1px solid", borderColor: "rgba(15,23,42,0.08)", background: `linear-gradient(135deg, ${selectedRewriteTemplate.accent}14 0%, rgba(255,255,255,0.96) 72%)` }}>
                        <Typography variant="caption" sx={{ display: "block", color: selectedRewriteTemplate.accent, fontWeight: 900, letterSpacing: '0.14em', mb: 0.5 }}>{selectedRewriteTemplate.eyebrow}</Typography>
                        <Typography sx={{ fontSize: { xs: '1.1rem', md: '1.35rem' }, fontWeight: 900, lineHeight: 1.1 }}>{selectedRewriteTemplate.sampleHeading}</Typography>
                        <Typography variant="body2" sx={{ color: "text.secondary", mt: 0.5 }}>{selectedRewriteTemplate.sampleMeta}</Typography>
                      </Box>
                      <Box sx={{ px: { xs: 2, md: 3 }, py: { xs: 2, md: 2.5 } }}>
                        <Typography variant="subtitle2" sx={{ fontWeight: 800, mb: 1 }}>Preview of the generated PDF style</Typography>
                        {selectedRewriteTemplate.sampleBullets.map((bullet) => (
                          <Typography key={bullet} variant="body2" sx={{ display: "block", color: "text.primary", mb: 0.85, lineHeight: 1.55 }}>• {bullet}</Typography>
                        ))}
                        <Box sx={{ mt: 2, pt: 1.5, borderTop: "1px dashed", borderColor: "divider", display: "grid", gridTemplateColumns: { xs: "1fr", sm: "repeat(3, minmax(0, 1fr))" }, gap: 1 }}>
                          <Chip size="small" variant="outlined" label="Readable hierarchy" />
                          <Chip size="small" variant="outlined" label="PDF-first spacing" />
                          <Chip size="small" variant="outlined" label="ATS-safe structure" />
                        </Box>
                      </Box>
                    </Box>
                  </Box>

                  <Box sx={{ display: "flex", flexDirection: "column", gap: 1.1 }}>
                    <Typography variant="subtitle2" sx={{ fontWeight: 900 }}>Choose a visual direction before generating</Typography>
                    <Box sx={{ display: "grid", gap: 1.1 }}>
                      {REWRITE_TEMPLATES.map((option) => {
                        const selected = option.id === cvSectionStyle;
                        return (
                          <Paper
                            key={option.id}
                            role="button"
                            tabIndex={0}
                            aria-label={`${option.title} template preview`}
                            onClick={() => setCvSectionStyle(option.id)}
                            onKeyDown={(event) => {
                              if (event.key === "Enter" || event.key === " ") {
                                event.preventDefault();
                                setCvSectionStyle(option.id);
                              }
                            }}
                            sx={{
                              p: 1.15,
                              borderRadius: 3,
                              cursor: "pointer",
                              border: "1px solid",
                              borderColor: selected ? "primary.main" : "divider",
                              background: selected ? `linear-gradient(180deg, ${option.accent}10 0%, rgba(255,255,255,0.98) 100%)` : "rgba(255,255,255,0.84)",
                              boxShadow: selected ? "0 0 0 1px rgba(25,118,210,0.16), 0 10px 24px rgba(15,23,42,0.08)" : "0 6px 16px rgba(15,23,42,0.04)",
                              transition: "transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease",
                              '&:hover': { transform: 'translateY(-1px)' },
                            }}
                          >
                            <Box sx={{ display: "grid", gridTemplateColumns: "92px minmax(0, 1fr)", gap: 1.1, alignItems: "stretch" }}>
                              <Box sx={{ borderRadius: 2.5, border: "1px solid", borderColor: "rgba(15,23,42,0.08)", background: `linear-gradient(180deg, ${option.accent}1e 0%, rgba(255,255,255,0.98) 100%)`, p: 1, minHeight: 102, display: "flex", flexDirection: "column", justifyContent: "space-between" }}>
                                <Typography variant="caption" sx={{ color: option.accent, fontWeight: 900, letterSpacing: '0.08em' }}>{option.eyebrow}</Typography>
                                <Box>
                                  <Typography variant="caption" sx={{ display: "block", fontWeight: 800, lineHeight: 1.25 }}>{option.sampleHeading}</Typography>
                                  <Typography variant="caption" sx={{ display: "block", color: "text.secondary", mt: 0.5, lineHeight: 1.25 }}>{option.sampleMeta}</Typography>
                                </Box>
                              </Box>
                              <Box sx={{ minWidth: 0 }}>
                                <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 1 }}>
                                  <Box sx={{ minWidth: 0 }}>
                                    <Typography variant="subtitle2" sx={{ fontWeight: 900 }}>{option.title}</Typography>
                                    <Typography variant="body2" sx={{ color: "text.secondary", mt: 0.25, lineHeight: 1.4 }}>{option.blurb}</Typography>
                                  </Box>
                                  {selected ? <Chip size="small" color="primary" label="Selected" /> : null}
                                </Box>
                              </Box>
                            </Box>
                          </Paper>
                        );
                      })}
                    </Box>
                  </Box>
                </Box>
              </Paper>
            </Box>

            <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1.5, mb: 1.75 }}>
              <TextField
                label="Prompt-based CV brief"
                value={cvPromptBackground}
                onChange={(e) => setCvPromptBackground(e.target.value)}
                fullWidth
                multiline
                minRows={4}
                helperText="Describe your strengths, preferred emphasis, industry background, or the angle you want the AI to lean into."
                sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }}
              />
              <FormControl fullWidth size="small">
                <InputLabel>{t("profileCvSectionLabel")}</InputLabel>
                <Select value={cvSection} label={t("profileCvSectionLabel")} onChange={(e) => setCvSection(e.target.value as CvSectionOption)}>
                  <MenuItem value="">Whole CV</MenuItem>
                  <MenuItem value="Professional Summary">{t("profileCvSectionSummary")}</MenuItem>
                  <MenuItem value="Core Skills">{t("profileCvSectionSkills")}</MenuItem>
                  <MenuItem value="Experience Highlights">{t("profileCvSectionExperience")}</MenuItem>
                  <MenuItem value="Selected Achievements">{t("profileCvSectionAchievements")}</MenuItem>
                  <MenuItem value="Projects">{t("profileCvSectionProjects")}</MenuItem>
                </Select>
              </FormControl>
              <TextField
                label={t("profileCvSectionTargetRole")}
                value={cvSectionTargetRole}
                onChange={(e) => setCvSectionTargetRole(e.target.value)}
                fullWidth
                helperText={selectedRewriteJob ? `Using saved job context: ${selectedRewriteJob.jobTitle}` : "Leave empty to let the selected job drive tailoring."}
              />
              <FormControl fullWidth size="small">
                <InputLabel>Language</InputLabel>
                <Select value={cvLanguage} label="Language" onChange={(e) => setCvLanguage(e.target.value as CvBuilderLanguage)}>
                  <MenuItem value="English">English</MenuItem>
                  <MenuItem value="Norwegian">Norwegian</MenuItem>
                  <MenuItem value="Spanish">Spanish</MenuItem>
                  <MenuItem value="French">French</MenuItem>
                  <MenuItem value="German">German</MenuItem>
                </Select>
              </FormControl>
              <FormControl fullWidth size="small">
                <InputLabel>Tone</InputLabel>
                <Select value={cvTone} label="Tone" onChange={(e) => setCvTone(e.target.value as CvBuilderTone)}>
                  <MenuItem value="Concise and direct">Concise and direct</MenuItem>
                  <MenuItem value="Executive and polished">Executive and polished</MenuItem>
                  <MenuItem value="Technical and detailed">Technical and detailed</MenuItem>
                  <MenuItem value="Warm and people-focused">Warm and people-focused</MenuItem>
                </Select>
              </FormControl>
              <FormControl fullWidth size="small" sx={{ gridColumn: { xs: "1 / -1", md: "1 / -1" } }}>
                <InputLabel>Saved job context</InputLabel>
                <Select value={selectedRewriteJobId} label="Saved job context" onChange={(e) => setSelectedRewriteJobId(String(e.target.value))}>
                  <MenuItem value="">None</MenuItem>
                  {savedJobs.map((job) => (
                    <MenuItem key={job.id} value={String(job.id)}>{job.jobTitle} · {job.company?.name ?? "Unknown company"}</MenuItem>
                  ))}
                </Select>
              </FormControl>
            </Box>

            <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, flexWrap: "wrap", alignItems: "center", mb: 1.5 }}>
              <Box>
                <Typography variant="subtitle2" sx={{ fontWeight: 900 }}>Builder output</Typography>
                <Typography variant="body2" sx={{ color: "text.secondary" }}>
                  {selectedRewriteTemplate.title} · {rewritePreview?.targetRole || selectedRewriteJob?.jobTitle || cvSectionTargetRole || "General reuse"}
                </Typography>
              </Box>
              <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
                <Button
                  variant="contained"
                  disabled={!isLocal || (!profileCvText.trim() && structuredCv.sections.length === 0) || rewritingSection || uploadingCv || improvingCv || rebuildingCv}
                  onClick={async () => {
                    setRewritingSection(true);
                    resetPdfCarousel();
                    try {
                      const res = await api.post<CvBuilderPreview>("/profile-cv/rewrite-preview", buildRewritePayload(cvSectionStyle));
                      setRewritePreview(res.data);
                      toast(t("profileCvSectionRewritten"), "success");
                    } catch (e: any) {
                      toast(getApiErrorMessage(e, t("profileCvSectionRewriteFailed")), "error");
                    } finally {
                      setRewritingSection(false);
                    }
                  }}
                >
                  {rewritingSection ? t("profileCvSectionRewriting") : rewriteReady ? "Refresh preview" : "Build preview"}
                </Button>
                <Button
                  variant="outlined"
                  disabled={!rewriteReady || downloadingPdf}
                  onClick={async () => {
                    setDownloadingPdf(true);
                    try {
                      await savePdfToCarousel(cvSectionStyle, true);
                      toast("CV PDF downloaded and added to the carousel.", "success");
                    } catch (e: any) {
                      toast(getApiErrorMessage(e, "Failed to export the CV PDF."), "error");
                    } finally {
                      setDownloadingPdf(false);
                    }
                  }}
                >
                  {downloadingPdf ? "Generating PDF…" : "Download PDF"}
                </Button>
                <Button
                  variant="text"
                  disabled={!rewriteReady || buildingPdfDeck}
                  onClick={buildPdfCarousel}
                >
                  {buildingPdfDeck ? "Building PDF carousel…" : "Build PDF carousel"}
                </Button>
              </Box>
            </Box>

            <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", xl: "0.9fr 1.1fr" }, gap: 1.5 }}>
              <Paper sx={{ p: 1.5, borderRadius: 3, border: "1px solid", borderColor: "divider", backgroundColor: "background.paper" }}>
                <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1, alignItems: "center", mb: 1 }}>
                  <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>{rewritePreview?.sectionName || "Full rewritten CV text"}</Typography>
                  {rewriteReady ? <Chip size="small" color="success" label={`${(rewritePreview?.fullText || "").trim().split(/\s+/).filter(Boolean).length} words`} /> : null}
                </Box>
                <Box sx={{ minHeight: 220, maxHeight: 520, overflow: "auto", borderRadius: 2.5, backgroundColor: "background.default", border: "1px dashed", borderColor: "divider", p: 1.5 }}>
                  {rewriteReady ? (
                    <Typography variant="body2" sx={{ whiteSpace: "pre-wrap" }}>{rewritePreview?.sectionName ? rewritePreview?.rewrittenText : rewritePreview?.fullText}</Typography>
                  ) : (
                    <Typography variant="body2" sx={{ color: "text.secondary" }}>Choose a template and generate a live preview. The builder will show rewritten content here and render the PDF layout beside it.</Typography>
                  )}
                </Box>
                <Box sx={{ mt: 1.25, display: "flex", justifyContent: "flex-end", gap: 1, flexWrap: "wrap" }}>
                  <Button variant="text" disabled={!rewriteReady} onClick={() => navigator.clipboard.writeText(rewritePreview?.fullText ?? "")}>{t("profileCopyCvText")}</Button>
                  <Button
                    variant="contained"
                    disabled={!rewriteReady}
                    onClick={() => {
                      setProfileCvText(rewritePreview?.fullText ?? "");
                      if (rewritePreview?.structuredCv) setStructuredCv(normalizeStructuredCv(rewritePreview.structuredCv));
                    }}
                  >
                    Replace master CV
                  </Button>
                </Box>
              </Paper>

              <Paper sx={{ p: 1.5, borderRadius: 3, border: "1px solid", borderColor: "divider", backgroundColor: "background.paper" }}>
                <Box sx={{ display: "flex", justifyContent: "space-between", gap: 1, alignItems: "center", mb: 1 }}>
                  <Box>
                    <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>PDF carousel</Typography>
                    <Typography variant="body2" sx={{ color: "text.secondary" }}>
                      {activePdfItem?.title ? `${activePdfItem.title} · generated PDF` : `${selectedRewriteTemplate.title} · print-ready layout`}
                    </Typography>
                  </Box>
                  {activePdfItem?.fileName ? <Chip size="small" variant="outlined" label={activePdfItem.fileName} /> : rewriteReady ? <Chip size="small" variant="outlined" label={rewritePreview?.suggestedFileName || "preview.pdf"} /> : null}
                </Box>

                {pdfCarousel.length > 0 ? (
                  <>
                    <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", mb: 1.25 }}>
                      {pdfCarousel.map((item, index) => (
                        <Button
                          key={item.templateId}
                          size="small"
                          variant={index === activePdfIndex ? "contained" : "outlined"}
                          color={item.status === "error" ? "error" : item.status === "ready" ? "primary" : "inherit"}
                          onClick={() => setActivePdfIndex(index)}
                        >
                          {item.title}
                        </Button>
                      ))}
                    </Box>
                    <Box sx={{ borderRadius: 2.5, border: "1px solid", borderColor: "divider", backgroundColor: "background.default", overflow: "hidden", minHeight: 520 }}>
                      {activePdfItem?.status === "ready" && activePdfItem.pdfUrl ? (
                        <iframe title={`${activePdfItem.title} PDF preview`} src={activePdfItem.pdfUrl} style={{ width: "100%", minHeight: 520, border: 0, background: "white" }} />
                      ) : activePdfItem?.status === "error" ? (
                        <Box sx={{ minHeight: 520, display: "grid", placeItems: "center", p: 3 }}>
                          <Box sx={{ maxWidth: 420, textAlign: "center" }}>
                            <Typography variant="subtitle2" sx={{ fontWeight: 900, mb: 1 }}>{activePdfItem.title} PDF unavailable</Typography>
                            <Typography variant="body2" sx={{ color: "text.secondary" }}>{activePdfItem.error || "This template could not be rendered as a PDF right now."}</Typography>
                          </Box>
                        </Box>
                      ) : (
                        <Box sx={{ minHeight: 520, display: "grid", placeItems: "center", p: 3 }}>
                          <Box sx={{ maxWidth: 420, textAlign: "center" }}>
                            <Typography variant="subtitle2" sx={{ fontWeight: 900, mb: 1 }}>{activePdfItem?.title || "Preparing PDF preview"}</Typography>
                            <Typography variant="body2" sx={{ color: "text.secondary" }}>
                              {buildingPdfDeck ? "The carousel is generating PDFs across the current template set." : "Generate the PDF carousel to inspect rendered export files without leaving the page."}
                            </Typography>
                          </Box>
                        </Box>
                      )}
                    </Box>
                  </>
                ) : (
                  <Box sx={{ borderRadius: 2.5, border: "1px solid", borderColor: "divider", backgroundColor: "background.default", overflow: "hidden", minHeight: 520 }}>
                    {rewriteReady ? (
                      <iframe title="Profile CV preview" srcDoc={rewritePreview?.html} style={{ width: "100%", minHeight: 520, border: 0, background: "white" }} />
                    ) : (
                      <Box sx={{ minHeight: 520, display: "grid", placeItems: "center", p: 3 }}>
                        <Typography variant="body2" sx={{ color: "text.secondary", textAlign: "center", maxWidth: 360 }}>
                          The visual preview uses the same server-rendered HTML that the PDF exporter prints. Build a preview to inspect layout, then generate the PDF carousel to compare rendered files template by template.
                        </Typography>
                      </Box>
                    )}
                  </Box>
                )}
              </Paper>
            </Box>

            <Dialog open={Boolean(rewritePreviewTemplate)} onClose={() => setRewritePreviewTemplate(null)} maxWidth="sm" fullWidth>
              <DialogTitle>{rewritePreviewTemplate?.title ?? "Template preview"}</DialogTitle>
              <DialogContent>
                {rewritePreviewTemplate ? (
                  <Box sx={{ p: 2, borderRadius: 3, border: "1px solid", borderColor: "divider", background: `linear-gradient(180deg, ${rewritePreviewTemplate.accent}12 0%, rgba(255,255,255,0) 100%)` }}>
                    <Typography variant="overline" sx={{ color: rewritePreviewTemplate.accent, fontWeight: 800 }}>{rewritePreviewTemplate.eyebrow}</Typography>
                    <Typography variant="h6" sx={{ fontWeight: 900, mb: 0.5 }}>{rewritePreviewTemplate.sampleHeading}</Typography>
                    <Typography variant="body2" sx={{ color: "text.secondary", mb: 1.5 }}>{rewritePreviewTemplate.sampleMeta}</Typography>
                    {rewritePreviewTemplate.sampleBullets.map((bullet) => (
                      <Typography key={bullet} variant="body2" sx={{ mb: 0.75 }}>• {bullet}</Typography>
                    ))}
                    <Typography variant="body2" sx={{ color: "text.secondary", mt: 1.5 }}>{rewritePreviewTemplate.blurb}</Typography>
                  </Box>
                ) : null}
              </DialogContent>
            </Dialog>
          </Box>
          <Box sx={{ mt: 1, display: "flex", justifyContent: "space-between", gap: 1, flexWrap: "wrap" }}>
            <Typography variant="caption" sx={{ color: "text.secondary" }}>
              {cvWordCount} words
            </Typography>
            <Typography variant="caption" sx={{ color: "text.secondary" }}>
              {t("profileCvPreferredUploads")}
            </Typography>
          </Box>
        </Box>

        <Box sx={{ gridColumn: "1 / -1", display: "flex", justifyContent: "flex-end", gap: 2, flexWrap: "wrap", alignItems: "center" }}>
          <Button
            variant="contained"
            disabled={!isLocal || loading}
            onClick={async () => {
              setLoading(true);
              try {
                // Scoped save: /career persists only the master profile, /profile only identity.
                // The backend (PUT /auth/profile) does partial updates — omitted fields are left
                // unchanged — so neither surface wipes the other's data.
                const payload = careerOnly
                  ? { profileCvText, profileCvStructureJson: JSON.stringify(structuredCv) }
                  : { email, userName, firstName, lastName, displayName };
                await api.put("/auth/profile", payload);
                if (!careerOnly) window.localStorage.setItem("profileHeadline", headline.trim());
                await loadProfile();
                toast(t("profileUpdated"), "success");
              } catch (e: any) {
                const msg = e?.response?.data || e?.message || t("profileUpdateFailed");
                toast(String(msg), "error");
              } finally {
                setLoading(false);
              }
            }}
          >
            {t("profileSaveChanges")}
          </Button>
        </Box>

        {!careerOnly ? <Box sx={{ gridColumn: "1 / -1", mt: 1 }}>
          <Divider sx={{ mb: 2 }} />
          <Typography variant="h6">{t("profileChangePassword")}</Typography>
          {!isLocal ? <Typography sx={{ color: "text.secondary" }}>{t("profilePasswordLocalOnly")}</Typography> : null}
        </Box> : null}

        {!careerOnly ? <>
          <TextField label={t("profileCurrentPassword")} type="password" value={currentPassword} onChange={(e) => setCurrentPassword(e.target.value)} disabled={!isLocal} fullWidth />
          <TextField label={t("profileNewPassword")} type="password" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} disabled={!isLocal} fullWidth />

          <Box sx={{ gridColumn: "1 / -1", display: "flex", justifyContent: "flex-end" }}>
          <Button
            variant="outlined"
            disabled={!isLocal || loading}
            onClick={async () => {
              setLoading(true);
              try {
                await api.post("/auth/change-password", { currentPassword, newPassword });
                setCurrentPassword("");
                setNewPassword("");
                toast(t("profilePasswordUpdated"), "success");
              } catch (e: any) {
                const msg = e?.response?.data || e?.message || t("profilePasswordUpdateFailed");
                toast(String(msg), "error");
              } finally {
                setLoading(false);
              }
            }}
          >
            {t("profileUpdatePassword")}
          </Button>
          </Box>
        </> : null}
      </Box>

      {!careerOnly && isLocal ? <TwoFactorSettingsCard /> : null}
      {!careerOnly && isLocal ? <SessionsSettingsCard /> : null}
    </Paper>
  );
}
