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

import {
  Alert, Box, Button, Chip, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Menu, MenuItem, Paper, Stack, TextField, Typography,
} from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
import DescriptionOutlinedIcon from "@mui/icons-material/DescriptionOutlined";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import PublicIcon from "@mui/icons-material/Public";

import { api, getApiErrorMessage } from "../api";
import { useToast } from "../toast";
import { CvTheme, CvVariantSummary, cvBuilderApi, emptyCvVariantSettings } from "../cvBuilder";
import { useDialogActions } from "../dialogs";
import CvTemplateThumbnail from "../components/CvTemplateThumbnail";
import { useI18n } from "../i18n/I18nProvider";

export default function CvBuilderPage() {
  const navigate = useNavigate();
  const { toast } = useToast();
  const { language, t } = useI18n();
  const { confirmAction, promptForValue } = useDialogActions();
  const [variants, setVariants] = useState<CvVariantSummary[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [menu, setMenu] = useState<{ anchor: HTMLElement; id: number } | null>(null);
  const [themes, setThemes] = useState<CvTheme[]>([]);
  const [createOpen, setCreateOpen] = useState(false);
  const [newName, setNewName] = useState(t("cvDashboardUntitled"));
  const [newTheme, setNewTheme] = useState("modern");
  const [creating, setCreating] = useState(false);

  const load = useCallback(async () => {
    try {
      setVariants(await cvBuilderApi.list());
      try { setThemes(await cvBuilderApi.themes()); } catch { setThemes([]); }
    } catch (err) {
      setError(getApiErrorMessage(err, t("cvDashboardLoadFailed")));
    } finally {
      setLoading(false);
    }
  }, [t]);
  useEffect(() => {
    void load();
  }, [load]);

  const createNew = async () => {
    setCreateOpen(true);
  };

  const confirmCreate = async () => {
    if (!newName.trim()) return;
    setCreating(true);
    try {
      const variant = await cvBuilderApi.create({ name: newName.trim(), settings: emptyCvVariantSettings(newTheme) });
      setCreateOpen(false);
      navigate(`/career/builder/${variant.id}`);
    } catch (err) {
      toast(getApiErrorMessage(err, t("cvDashboardCreateFailed")), "error");
    } finally { setCreating(false); }
  };

  const duplicate = async (id: number) => {
    try {
      await cvBuilderApi.duplicate(id);
      await load();
      toast(t("cvDashboardDuplicated"), "success");
    } catch (err) {
      toast(getApiErrorMessage(err, t("cvDashboardDuplicateFailed")), "error");
    } finally {
      setMenu(null);
    }
  };

  const remove = async (id: number) => {
    const variant = variants.find((item) => item.id === id);
    setMenu(null);
    if (!(await confirmAction(t("cvDashboardDeleteMessage", { name: variant?.name ?? t("cvDashboardThisCv") }), {
      title: t("cvDashboardDeleteCv"),
      confirmLabel: t("cvDashboardDeleteCv"),
      destructive: true,
    }))) return;
    try {
      await cvBuilderApi.remove(id);
      setVariants((v) => v.filter((x) => x.id !== id));
      toast(t("cvDashboardDeleted"), "success");
    } catch (err) {
      toast(getApiErrorMessage(err, t("cvDashboardDeleteFailed")), "error");
    } finally {
      setMenu(null);
    }
  };

  const rename = async (id: number) => {
    const current = variants.find((item) => item.id === id);
    setMenu(null);
    const nextName = await promptForValue(t("cvDashboardRenameMessage"), current?.name ?? "", { title: t("cvDashboardRenameCv"), confirmLabel: t("cvDashboardRename") });
    if (!nextName?.trim() || nextName.trim() === current?.name) return;
    try {
      const variant = await cvBuilderApi.get(id);
      const updated = await cvBuilderApi.save(id, { name: nextName.trim(), settings: variant.settings, source: "manual" });
      setVariants((items) => items.map((item) => item.id === id ? { ...item, name: updated.name, updatedAtUtc: updated.updatedAtUtc, version: updated.version } : item));
      toast(t("cvDashboardRenamed"), "success");
    } catch (err) { toast(getApiErrorMessage(err, t("cvDashboardRenameFailed")), "error"); }
  };

  const download = async (id: number, cvName: string) => {
    setMenu(null);
    try {
      const response = await api.post(cvBuilderApi.exportPdfUrl(id), {}, { responseType: "blob" });
      const url = URL.createObjectURL(response.data as Blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = `${cvName || "cv"}.pdf`;
      link.click();
      URL.revokeObjectURL(url);
    } catch (err) { toast(getApiErrorMessage(err, t("cvDashboardDownloadFailed")), "error"); }
  };

  return (
    <Box sx={{ display: "grid", gap: 2 }}>
      <Paper sx={{ p: { xs: 2, sm: 3 }, borderRadius: 3, display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 2, background: "linear-gradient(120deg, rgba(49,87,213,.09), transparent 58%)", border: "1px solid", borderColor: "divider" }}>
        <Box>
          <Typography variant="h5" sx={{ fontWeight: 900 }}>{t("cvDashboardTitle")}</Typography>
          <Typography color="text.secondary" sx={{ maxWidth: 720 }}>{t("cvDashboardSubtitle")}</Typography>
        </Box>
        <Button variant="contained" startIcon={<AddIcon />} onClick={createNew}>{t("cvDashboardNewCv")}</Button>
      </Paper>

      {error && <Alert severity="error">{error}</Alert>}

      {!loading && variants.length === 0 && !error && (
        <Paper sx={{ p: 4, borderRadius: 4, textAlign: "center" }}>
          <DescriptionOutlinedIcon sx={{ fontSize: 48, color: "text.disabled" }} />
          <Typography sx={{ mt: 1, fontWeight: 700 }}>{t("cvDashboardEmptyTitle")}</Typography>
          <Typography color="text.secondary" sx={{ mb: 2 }}>{t("cvDashboardEmptyBody")}</Typography>
          <Button variant="contained" startIcon={<AddIcon />} onClick={createNew}>{t("cvDashboardNewCv")}</Button>
        </Paper>
      )}

      <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", sm: "repeat(2, minmax(0, 1fr))", lg: "repeat(3, minmax(0, 1fr))" }, gap: 2 }}>
        {variants.map((v) => (
          <Paper
            key={v.id}
            role="link"
            tabIndex={0}
            aria-label={t("cvDashboardOpenNamed", { name: v.name })}
            sx={{ p: 1.5, borderRadius: 3, cursor: "pointer", border: "1px solid", borderColor: "divider", transition: "transform 150ms ease, box-shadow 150ms ease", "&:hover": { boxShadow: 5, transform: "translateY(-2px)" }, "&:focus-visible": { outline: "3px solid", outlineColor: "primary.main", outlineOffset: 2 } }}
            onClick={() => navigate(`/career/builder/${v.id}`)}
            onKeyDown={(event) => {
              if (event.target === event.currentTarget && (event.key === "Enter" || event.key === " ")) {
                event.preventDefault();
                navigate(`/career/builder/${v.id}`);
              }
            }}
            >
            <CvTemplateThumbnail theme={themes.find((theme) => theme.id === v.themeId)} />
            <Stack direction="row" alignItems="flex-start" justifyContent="space-between">
              <Typography sx={{ fontWeight: 800, mt: 1 }}>{v.name}</Typography>
              <IconButton size="small" aria-label={t("cvDashboardActionsFor", { name: v.name })} onClick={(e) => { e.stopPropagation(); setMenu({ anchor: e.currentTarget, id: v.id }); }}>
                <MoreVertIcon fontSize="small" />
              </IconButton>
            </Stack>
            <Stack direction="row" spacing={1} sx={{ mt: 1 }}>
              <Chip size="small" label={v.themeId} />
              <Chip size="small" variant="outlined" label={(v.language || "en").toUpperCase()} />
              {v.isPublic && <Chip size="small" color="primary" icon={<PublicIcon />} label={t("cvEditorPublic")} />}
            </Stack>
            <Typography variant="caption" color="text.secondary" sx={{ display: "block", mt: 1 }}>
              {t("cvDashboardUpdatedVersion", { date: new Date(v.updatedAtUtc).toLocaleDateString(language === "nb" ? "nb-NO" : "en-GB"), version: v.version })}
              {v.jobApplicationId ? ` · ${[v.jobTitle, v.companyName].filter(Boolean).join(t("cvDashboardAt")) || t("cvDashboardJobNumber", { id: v.jobApplicationId })}` : ""}
            </Typography>
          </Paper>
        ))}
      </Box>

      <Menu anchorEl={menu?.anchor} open={!!menu} onClose={() => setMenu(null)}>
        <MenuItem onClick={() => menu && navigate(`/career/builder/${menu.id}`)}>{t("cvDashboardOpen")}</MenuItem>
        <MenuItem onClick={() => menu && duplicate(menu.id)}>{t("cvEditorDuplicate")}</MenuItem>
        <MenuItem onClick={() => menu && void rename(menu.id)}>{t("cvDashboardRename")}</MenuItem>
        <MenuItem onClick={() => { const cv = variants.find((item) => item.id === menu?.id); if (cv) void download(cv.id, cv.name); }}>{t("cvEditorDownloadPdf")}</MenuItem>
        <MenuItem onClick={() => menu && remove(menu.id)} sx={{ color: "error.main" }}>{t("cvDashboardDelete")}</MenuItem>
      </Menu>

      <Dialog open={createOpen} onClose={() => { if (!creating) setCreateOpen(false); }} fullWidth maxWidth="md" aria-labelledby="create-cv-title">
        <DialogTitle id="create-cv-title">{t("cvDashboardCreateTitle")}</DialogTitle>
        <DialogContent>
          <Typography color="text.secondary" sx={{ mb: 2 }}>{t("cvDashboardCreateHelp")}</Typography>
          <TextField autoFocus fullWidth label={t("cvEditorName")} value={newName} onChange={(event) => setNewName(event.target.value)} error={!newName.trim()} helperText={!newName.trim() ? t("cvDashboardEnterName") : t("cvDashboardNameExample")} sx={{ mb: 2 }} />
          <Typography variant="subtitle2" sx={{ fontWeight: 800, mb: 1 }}>{t("cvDashboardChooseTemplate")}</Typography>
          <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr 1fr", sm: "repeat(4, 1fr)" }, gap: 1 }}>
            {(themes.length ? themes.filter((theme) => theme.available) : [{ id: "modern", name: "Modern", category: "Professional", layout: "header-band", swatches: ["#3157d5", "#eef1f4", "#fff"] } as CvTheme]).map((theme) => <Paper key={theme.id} role="button" tabIndex={0} aria-pressed={newTheme === theme.id} onClick={() => setNewTheme(theme.id)} onKeyDown={(event) => { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); setNewTheme(theme.id); } }} variant="outlined" sx={{ p: 0.75, cursor: "pointer", borderWidth: newTheme === theme.id ? 2 : 1, borderColor: newTheme === theme.id ? "primary.main" : "divider", "&:focus-visible": { outline: "3px solid", outlineColor: "primary.main" } }}><CvTemplateThumbnail theme={theme} height={105} /><Typography variant="body2" sx={{ fontWeight: 700, mt: 0.75 }}>{theme.name}</Typography><Typography variant="caption" color="text.secondary">{theme.category}</Typography></Paper>)}
          </Box>
        </DialogContent>
        <DialogActions><Button onClick={() => setCreateOpen(false)} disabled={creating}>{t("cancel")}</Button><Button variant="contained" disabled={creating || !newName.trim()} onClick={() => void confirmCreate()}>{creating ? t("cvDashboardCreating") : t("cvDashboardCreateCv")}</Button></DialogActions>
      </Dialog>
    </Box>
  );
}
