import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import {
  Box,
  Alert,
  Autocomplete,
  Chip,
  CircularProgress,
  FormControl,
  InputLabel,
  MenuItem,
  Pagination,
  Paper,
  Select,
  Stack,
  TextField,
  Typography,
  Button,
} from "@mui/material";
import MailOutlineIcon from "@mui/icons-material/MailOutline";
import { api, getApiErrorMessage } from "../api";
import { useConfirm } from "../confirm";
import { useToast } from "../toast";
import { useI18n } from "../i18n/I18nProvider";
import GmailReviewPage from "./GmailReviewPage";

export type CorrespondenceInboxItem = {
  id: number;
  jobApplicationId: number;
  companyName?: string | null;
  jobTitle?: string | null;
  from: string;
  direction?: string | null;
  subject?: string | null;
  channel?: string | null;
  date: string;
  contentPreview: string;
  externalThreadId?: string | null;
  externalMessageId?: string | null;
  provider?: string | null;
  externalFrom?: string | null;
  externalTo?: string | null;
  labelCount: number;
  attachmentCount: number;
};

type CorrespondenceInboxPage = {
  items: CorrespondenceInboxItem[];
  page: number;
  pageSize: number;
  total: number;
  totalPages: number;
};

type EmailProviderStatus = {
  provider: string;
  displayName: string;
  connected: boolean;
  address?: string | null;
  canRead: boolean;
  canSend: boolean;
};

type JobChoice = {
  id: number;
  jobTitle: string;
  companyName: string;
};

type EmailMessageDetail = {
  id: string;
  threadId: string;
  subject: string;
  from: string;
  to: string;
  date?: string | null;
  snippet: string;
  bodyText: string;
  labels: string[];
  attachments: Array<{ fileName?: string | null; mimeType?: string | null; sizeBytes?: number | null }>;
};

type EmailDraft = {
  id?: string;
  revision?: number;
  jobApplicationId: number;
  companyName: string;
  jobTitle: string;
  provider: string;
  providerName: string;
  fromAddress: string;
  to: string;
  subject: string;
  bodyText: string;
  threadId: string;
  clientRequestId: string;
};

type StoredEmailDraft = Pick<EmailDraft, "id" | "revision" | "jobApplicationId" | "provider" | "to" | "subject" | "bodyText" | "threadId" | "clientRequestId"> & {
  id: string;
  revision: number;
  createdAtUtc: string;
  updatedAtUtc: string;
};

type EmailSendResult = {
  attemptId: string;
  status: "pending" | "sending" | "sent" | "failed" | "uncertain";
  duplicate: boolean;
  externalMessageId?: string | null;
  externalThreadId?: string | null;
  failureCategory?: string | null;
};

export default function CorrespondenceInboxPage() {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const view = searchParams.get("view") === "review" ? "review" : "inbox";
  const { toast } = useToast();
  const { confirm } = useConfirm();
  const { language, t } = useI18n();
  const [items, setItems] = useState<CorrespondenceInboxItem[]>([]);
  const [inboxPage, setInboxPage] = useState(1);
  const [inboxTotal, setInboxTotal] = useState(0);
  const [inboxTotalPages, setInboxTotalPages] = useState(0);
  const [providers, setProviders] = useState<EmailProviderStatus[]>([]);
  const [providerStatusLoaded, setProviderStatusLoaded] = useState(false);
  const [jobs, setJobs] = useState<JobChoice[]>([]);
  const [jobsLoaded, setJobsLoaded] = useState(false);
  const [jobsLoading, setJobsLoading] = useState(false);
  const [jobQuery, setJobQuery] = useState("");
  const [composeSetupOpen, setComposeSetupOpen] = useState(false);
  const [composeJobId, setComposeJobId] = useState<number | "">("");
  const [composeProvider, setComposeProvider] = useState("");
  const [providerStatusError, setProviderStatusError] = useState(false);
  const [selectedMessageId, setSelectedMessageId] = useState<number | null>(null);
  const [messageDetail, setMessageDetail] = useState<EmailMessageDetail | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [detailError, setDetailError] = useState<string | null>(null);
  const [detailNotice, setDetailNotice] = useState<string | null>(null);
  const detailRequest = useRef(0);
  const [loading, setLoading] = useState(false);
  const [query, setQuery] = useState("");
  const [direction, setDirection] = useState<string>("all");
  const [linkState, setLinkState] = useState<string>("all");
  const [draft, setDraft] = useState<EmailDraft | null>(null);
  const [storedDrafts, setStoredDrafts] = useState<StoredEmailDraft[]>([]);
  const [savingDraft, setSavingDraft] = useState(false);
  const [draftError, setDraftError] = useState<string | null>(null);
  const [sendResult, setSendResult] = useState<EmailSendResult | null>(null);
  const [sendError, setSendError] = useState<string | null>(null);
  const [sending, setSending] = useState(false);
  const [unlinkingThreadId, setUnlinkingThreadId] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await api.get<CorrespondenceInboxPage>("/correspondence/page", {
        params: {
          q: query.trim() || undefined,
          direction: direction === "all" ? undefined : direction,
          linkState: linkState === "all" ? undefined : linkState,
          page: inboxPage,
          pageSize: 50,
        },
      });
      setItems(res.data?.items ?? []);
      setInboxTotal(res.data?.total ?? 0);
      setInboxTotalPages(res.data?.totalPages ?? 0);
      if (res.data?.page && res.data.page !== inboxPage) setInboxPage(res.data.page);
      setSelectedMessageId(null);
      setMessageDetail(null);
    } catch (error) {
      toast(getApiErrorMessage(error, t("emailInboxLoadFailed")), "error");
    } finally {
      setLoading(false);
    }
  }, [direction, inboxPage, linkState, query, t, toast]);

  useEffect(() => {
    if (view === "inbox") void load();
  }, [load, view]);

  useEffect(() => {
    api.get<EmailProviderStatus[]>("/email/providers")
      .then((response) => {
        setProviders(response.data ?? []);
        setProviderStatusError(false);
      })
      .catch(() => {
        setProviders([]);
        setProviderStatusError(true);
      })
      .finally(() => setProviderStatusLoaded(true));
  }, []);

  useEffect(() => {
    const timer = window.setTimeout(() => {
      setJobsLoading(true);
      api.get<JobChoice[]>("/jobapplications/choices", { params: { q: jobQuery.trim() || undefined, limit: 20 } })
        .then((response) => setJobs(Array.isArray(response.data) ? response.data : []))
        .catch(() => setJobs([]))
        .finally(() => {
          setJobsLoaded(true);
          setJobsLoading(false);
        });
    }, jobQuery.trim() ? 250 : 0);
    return () => window.clearTimeout(timer);
  }, [jobQuery]);

  const loadStoredDrafts = useCallback(async () => {
    try {
      const response = await api.get<StoredEmailDraft[]>("/email/drafts");
      setStoredDrafts(Array.isArray(response.data) ? response.data : []);
    } catch {
      setDraftError(t("emailInboxDraftsLoadFailed"));
    }
  }, [t]);

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

  const filteredSummary = useMemo(() => {
    const linked = items.filter((item) => item.externalThreadId).length;
    const inbound = items.filter((item) => item.direction === "inbound").length;
    return { linked, inbound };
  }, [items]);
  const sendCapableProviders = useMemo(() => providers.filter((provider) => provider.connected && provider.canSend), [providers]);

  const showMessage = async (item: CorrespondenceInboxItem) => {
    if (selectedMessageId === item.id) {
      detailRequest.current += 1;
      setSelectedMessageId(null);
      setMessageDetail(null);
      return;
    }

    const request = ++detailRequest.current;
    setSelectedMessageId(item.id);
    setMessageDetail(null);
    setDetailError(null);
    setDetailNotice(null);
    setDetailLoading(true);
    try {
      if (item.provider && item.provider !== "manual" && item.externalMessageId) {
        try {
          const live = await api.get<EmailMessageDetail>("/email/message", {
            params: { provider: item.provider, messageId: item.externalMessageId },
          });
          if (request !== detailRequest.current) return;
          setMessageDetail(live.data);
          return;
        } catch {
          if (request !== detailRequest.current) return;
          setDetailNotice(t("emailInboxProviderCopyUnavailable"));
        }
      }

      const saved = await api.get<EmailMessageDetail>(`/correspondence/message/${item.id}`);
      if (request !== detailRequest.current) return;
      setMessageDetail(saved.data);
    } catch (error) {
      if (request !== detailRequest.current) return;
      setDetailError(getApiErrorMessage(error, t("emailInboxMessageLoadFailed")));
    } finally {
      if (request === detailRequest.current) setDetailLoading(false);
    }
  };

  const startReply = async (item: CorrespondenceInboxItem) => {
    if (!messageDetail || !item.provider) return;
    const provider = providers.find((candidate) => candidate.provider === item.provider);
    if (!provider?.canSend) return;
    if (draft?.bodyText.trim() && !(await confirm({
      title: t("emailInboxReplaceDraftTitle"),
      message: t("emailInboxReplaceReplyMessage"),
      confirmLabel: t("emailInboxReplaceDraft"),
      destructive: true,
    }))) return;
    const subject = messageDetail.subject.trim();
    setDraft({
      jobApplicationId: item.jobApplicationId,
      companyName: item.companyName || t("emailInboxUnknownCompany"),
      jobTitle: item.jobTitle || t("emailInboxUnknownRole"),
      provider: item.provider,
      providerName: provider.displayName,
      fromAddress: provider.address || t("emailInboxConnectedAccount"),
      to: item.direction === "outbound" ? messageDetail.to : messageDetail.from,
      subject: /^re:/i.test(subject) ? subject : `Re: ${subject || t("emailInboxYourMessage")}`,
      bodyText: "",
      threadId: messageDetail.threadId || item.externalThreadId || "",
      clientRequestId: globalThis.crypto.randomUUID(),
    });
    setSendResult(null);
    setSendError(null);
    setDraftError(null);
  };

  const resumeDraft = async (stored: StoredEmailDraft) => {
    if (draft?.bodyText.trim() && !(await confirm({
      title: t("emailInboxReplaceDraftTitle"),
      message: draft.id ? t("emailInboxCurrentDraftSaved") : t("emailInboxUnsavedDraftLost"),
      confirmLabel: t("emailInboxReplaceDraft"),
      destructive: !draft.id,
    }))) return;
    const provider = providers.find((candidate) => candidate.provider === stored.provider);
    const item = items.find((candidate) => candidate.jobApplicationId === stored.jobApplicationId);
    setDraft({
      ...stored,
      companyName: item?.companyName || `Job #${stored.jobApplicationId}`,
      jobTitle: item?.jobTitle || t("emailInboxSavedDraft"),
      providerName: provider?.displayName || stored.provider,
      fromAddress: provider?.address || t("emailInboxReconnectBeforeSending"),
    });
    setSendResult(null);
    setSendError(null);
    setDraftError(null);
  };

  const openComposeSetup = () => {
    setComposeJobId((current) => current || jobs[0]?.id || "");
    setComposeProvider((current) => current || sendCapableProviders[0]?.provider || "");
    setComposeSetupOpen(true);
  };

  const startNewMessage = async () => {
    const job = jobs.find((candidate) => candidate.id === composeJobId);
    const provider = sendCapableProviders.find((candidate) => candidate.provider === composeProvider);
    if (!job || !provider) return;
    if (draft?.bodyText.trim() && !(await confirm({
      title: t("emailInboxReplaceDraftTitle"),
      message: draft.id ? t("emailInboxCurrentDraftSaved") : t("emailInboxUnsavedDraftLost"),
      confirmLabel: t("emailInboxReplaceDraft"),
      destructive: !draft.id,
    }))) return;
    setDraft({
      jobApplicationId: job.id,
      companyName: job.companyName || t("emailInboxUnknownCompany"),
      jobTitle: job.jobTitle || t("emailInboxUnknownRole"),
      provider: provider.provider,
      providerName: provider.displayName,
      fromAddress: provider.address || t("emailInboxConnectedAccount"),
      to: "",
      subject: "",
      bodyText: "",
      threadId: "",
      clientRequestId: globalThis.crypto.randomUUID(),
    });
    setComposeSetupOpen(false);
    setSendResult(null);
    setSendError(null);
    setDraftError(null);
  };

  const updateDraft = (changes: Partial<Pick<EmailDraft, "to" | "subject" | "bodyText">>) => {
    setDraft((current) => current ? {
      ...current,
      ...changes,
      clientRequestId: sendResult ? globalThis.crypto.randomUUID() : current.clientRequestId,
    } : null);
    if (sendResult) setSendResult(null);
    setSendError(null);
  };

  const discardDraft = async () => {
    if (draft?.bodyText.trim() && !(await confirm({
      title: t("emailInboxDiscardDraftTitle"),
      message: t("emailInboxDiscardDraftMessage"),
      confirmLabel: t("emailInboxDiscardDraft"),
      destructive: true,
    }))) return;
    if (draft?.id && draft.revision) {
      try {
        await api.delete(`/email/drafts/${draft.id}`, { params: { revision: draft.revision } });
        await loadStoredDrafts();
      } catch (error) {
        setDraftError(getApiErrorMessage(error, t("emailInboxDraftChangedDiscard")));
        return;
      }
    }
    setDraft(null);
    setSendResult(null);
    setSendError(null);
    setDraftError(null);
  };

  const saveDraft = async () => {
    if (!draft || savingDraft || sendResult) return;
    setSavingDraft(true);
    setDraftError(null);
    try {
      const response = draft.id && draft.revision
        ? await api.put<StoredEmailDraft>(`/email/drafts/${draft.id}`, {
            revision: draft.revision,
            to: draft.to,
            subject: draft.subject,
            bodyText: draft.bodyText,
          })
        : await api.post<StoredEmailDraft>("/email/drafts", {
            jobApplicationId: draft.jobApplicationId,
            provider: draft.provider,
            to: draft.to,
            subject: draft.subject,
            bodyText: draft.bodyText,
            threadId: draft.threadId || null,
          });
      setDraft((current) => current ? { ...current, ...response.data } : null);
      await loadStoredDrafts();
      toast(t("emailInboxDraftSaved"), "success");
    } catch (error: any) {
      setDraftError(error?.response?.status === 409
        ? t("emailInboxDraftChangedElsewhere")
        : getApiErrorMessage(error, t("emailInboxDraftSaveFailed")));
    } finally {
      setSavingDraft(false);
    }
  };

  const sendDraft = async () => {
    if (!draft || sending || !draft.to.trim() || !draft.subject.trim() || !draft.bodyText.trim()) return;
    const approved = await confirm({
      title: t("emailInboxConfirmSendTitle"),
      message: t("emailInboxConfirmSendMessage", { provider: draft.providerName, from: draft.fromAddress, to: draft.to.trim(), subject: draft.subject.trim(), thread: draft.threadId || t("emailInboxNewMessage") }),
      confirmLabel: t("emailInboxSendEmail"),
    });
    if (!approved) return;

    setSending(true);
    setSendError(null);
    try {
      const response = await api.post<EmailSendResult>("/email/send", {
        jobApplicationId: draft.jobApplicationId,
        provider: draft.provider,
        clientRequestId: draft.clientRequestId,
        to: draft.to.trim(),
        subject: draft.subject.trim(),
        bodyText: draft.bodyText,
        threadId: draft.threadId || null,
        confirmed: true,
      });
      setSendResult(response.data);
      if (response.data.status === "sent") {
        toast(t("emailInboxSentSaved"), "success");
        if (draft.id && draft.revision) {
          try {
            await api.delete(`/email/drafts/${draft.id}`, { params: { revision: draft.revision } });
            setDraft((current) => current ? { ...current, id: undefined, revision: undefined } : null);
            await loadStoredDrafts();
          } catch {
            toast(t("emailInboxSentNewerDraft"), "warning");
          }
        }
        await load();
      }
    } catch (error: any) {
      const result = error?.response?.data;
      if (["failed", "uncertain", "sent", "pending", "sending"].includes(result?.status)) {
        setSendResult(result as EmailSendResult);
      } else if (!error?.response || error.response.status >= 500) {
        setSendResult({ attemptId: draft.clientRequestId, status: "uncertain", duplicate: false, failureCategory: "client_connection_lost" });
      } else {
        setSendResult({ attemptId: draft.clientRequestId, status: "failed", duplicate: false });
      }
      setSendError(getApiErrorMessage(error, t("emailInboxSendFailed")));
    } finally {
      setSending(false);
    }
  };

  const prepareNewAttempt = async () => {
    if (!draft || sendResult?.status !== "failed") return;
    setDraftError(null);
    if (draft.id && draft.revision) {
      try {
        const response = await api.post<StoredEmailDraft>(`/email/drafts/${draft.id}/new-attempt`, { revision: draft.revision });
        setDraft((current) => current ? { ...current, ...response.data } : null);
        await loadStoredDrafts();
      } catch (error: any) {
        setDraftError(error?.response?.status === 409
          ? t("emailInboxNewAttemptConflict")
          : getApiErrorMessage(error, t("emailInboxNewAttemptFailed")));
        return;
      }
    } else {
      setDraft((current) => current ? { ...current, clientRequestId: globalThis.crypto.randomUUID() } : null);
    }
    setSendResult(null);
    setSendError(null);
  };

  const unlinkGmailThread = async (item: CorrespondenceInboxItem) => {
    if (item.provider !== "gmail" || !item.externalThreadId || unlinkingThreadId) return;
    if (!(await confirm({
      title: t("emailInboxUnlinkTitle"),
      message: t("emailInboxUnlinkMessage", { job: item.companyName || t("emailInboxThisJob") }),
      confirmLabel: t("emailInboxUnlinkThread"),
      destructive: true,
    }))) return;

    setUnlinkingThreadId(item.externalThreadId);
    try {
      await api.post("/gmail/unlink-thread", {
        jobApplicationId: item.jobApplicationId,
        threadId: item.externalThreadId,
        note: "Unlinked from Job email hub",
        nextDecision: "review",
      });
      if (selectedMessageId === item.id) {
        detailRequest.current += 1;
        setSelectedMessageId(null);
        setMessageDetail(null);
      }
      await load();
      toast(t("emailInboxUnlinked"), "success");
    } catch (error) {
      toast(getApiErrorMessage(error, t("emailInboxUnlinkFailed")), "error");
    } finally {
      setUnlinkingThreadId(null);
    }
  };

  const providerStatusLabel = (provider: EmailProviderStatus) => {
    if (!provider.connected) return t("emailInboxProviderNotConnected", { provider: provider.displayName });
    const identity = provider.address || t("emailInboxConnectedAccount");
    if (!provider.canRead) return t("emailInboxProviderReadUnavailable", { provider: provider.displayName, identity });
    return t(provider.canSend ? "emailInboxProviderReadSend" : "emailInboxProviderReadOnly", { provider: provider.displayName, identity });
  };

  return (
    <Paper
      sx={{
        mt: 0,
        p: 2,
        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)",
      }}
    >
      <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, alignItems: "center", flexWrap: "wrap", mb: 2 }}>
        <Box>
          <Typography component="h1" variant="h5" sx={{ fontWeight: 900 }}>{t("correspondenceInbox")}</Typography>
          <Typography variant="body2" sx={{ color: "text.secondary" }}>
            {t("emailInboxSubtitle")}
          </Typography>
        </Box>
        <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", alignItems: "center" }}>
          {view === "inbox" ? <Chip icon={<MailOutlineIcon />} label={t("emailInboxItems", { count: inboxTotal })} variant="outlined" /> : null}
          {view === "inbox" ? <Chip label={t("emailInboxLinked", { count: filteredSummary.linked })} variant="outlined" color={filteredSummary.linked > 0 ? "success" : "default"} /> : null}
          {view === "inbox" ? <Chip label={t("emailInboxInboundCount", { count: filteredSummary.inbound })} variant="outlined" /> : null}
          <Button variant={view === "inbox" ? "contained" : "text"} size="small" onClick={() => setSearchParams({})}>{t("emailInboxLinkedMessages")}</Button>
          <Button variant={view === "review" ? "contained" : "text"} size="small" onClick={() => setSearchParams({ view: "review" })}>{t("emailInboxReviewSuggestions")}</Button>
          <Button variant="outlined" size="small" onClick={openComposeSetup} disabled={jobs.length === 0 || sendCapableProviders.length === 0}>{t("emailInboxCompose")}</Button>
        </Box>
      </Box>

      <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", mb: 2 }} aria-label={t("emailInboxProviderStatus")}>
        {providers.map((provider) => (
          <Chip
            key={provider.provider}
            size="small"
            color={provider.connected ? "success" : "default"}
            variant="outlined"
            label={providerStatusLabel(provider)}
          />
        ))}
      </Box>
      {providerStatusError ? (
        <Alert severity="warning" sx={{ mb: 2 }}>{t("emailInboxProviderStatusUnavailable")}</Alert>
      ) : null}
      {jobsLoaded && jobs.length === 0 ? <Alert severity="info" sx={{ mb: 2 }}>{t("emailInboxAddJobFirst")}</Alert> : null}
      {providerStatusLoaded && !providerStatusError && sendCapableProviders.length === 0 ? <Alert severity="info" sx={{ mb: 2 }}>{t("emailInboxReconnectToCompose")}</Alert> : null}
      {draftError && !draft ? <Alert severity="warning" sx={{ mb: 2 }}>{draftError}</Alert> : null}

      {storedDrafts.length > 0 ? (
        <Alert severity="info" sx={{ mb: 2 }}>
          <Stack direction="row" spacing={1} useFlexGap flexWrap="wrap" alignItems="center">
            <Typography variant="body2">{t(storedDrafts.length === 1 ? "emailInboxSavedDraftOne" : "emailInboxSavedDraftMany", { count: storedDrafts.length })}</Typography>
            {storedDrafts.slice(0, 5).map((stored) => (
              <Button key={stored.id} size="small" onClick={() => void resumeDraft(stored)}>
                {t("emailInboxResumeDraft", { name: stored.subject || `${t("emailInboxJobNumber")} #${stored.jobApplicationId}` })}
              </Button>
            ))}
          </Stack>
        </Alert>
      ) : null}

      {composeSetupOpen ? (
        <Paper component="section" aria-labelledby="compose-new-title" variant="outlined" sx={{ p: 2, borderRadius: 3, mb: 2 }}>
          <Typography id="compose-new-title" component="h2" variant="h6" sx={{ fontWeight: 900, mb: 1.5 }}>{t("emailInboxCompose")}</Typography>
          <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr auto" }, gap: 1.25, alignItems: "center" }}>
            <Autocomplete
              options={jobs}
              loading={jobsLoading}
              value={jobs.find((job) => job.id === composeJobId) ?? null}
              onInputChange={(_, value, reason) => {
                if (reason === "input" || reason === "clear") setJobQuery(value);
              }}
              onChange={(_, value) => setComposeJobId(value?.id ?? "")}
              isOptionEqualToValue={(option, value) => option.id === value.id}
              getOptionLabel={(job) => `${job.companyName || t("emailInboxUnknownCompany")} · ${job.jobTitle}`}
              renderInput={(params) => <TextField {...params} label={t("emailInboxJob")} placeholder={t("emailInboxSearchJobs")} />}
            />
            <FormControl fullWidth>
              <InputLabel id="compose-provider-label">{t("emailInboxSendingProvider")}</InputLabel>
              <Select labelId="compose-provider-label" value={composeProvider} label={t("emailInboxSendingProvider")} onChange={(event) => setComposeProvider(String(event.target.value))}>
                {sendCapableProviders.map((provider) => <MenuItem key={provider.provider} value={provider.provider}>{provider.displayName} · {provider.address || t("emailInboxConnectedAccount")}</MenuItem>)}
              </Select>
            </FormControl>
            <Box sx={{ display: "flex", gap: 1 }}>
              <Button onClick={() => setComposeSetupOpen(false)}>{t("cancel")}</Button>
              <Button variant="contained" onClick={() => void startNewMessage()} disabled={!composeJobId || !composeProvider}>{t("emailInboxStartDraft")}</Button>
            </Box>
          </Box>
        </Paper>
      ) : null}

      {view === "review" ? <GmailReviewPage embedded /> : <>
        <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "2fr 1fr 1fr auto" }, gap: 1.25, mb: 2 }}>
        <TextField label={t("correspondenceSearch")} value={query} onChange={(e) => { setQuery(e.target.value); setInboxPage(1); }} placeholder={t("emailInboxSearchPlaceholder")} />
        <FormControl fullWidth>
          <InputLabel id="email-direction-label">{t("emailInboxDirection")}</InputLabel>
          <Select labelId="email-direction-label" value={direction} label={t("emailInboxDirection")} onChange={(e) => { setDirection(String(e.target.value)); setInboxPage(1); }}>
            <MenuItem value="all">{t("emailInboxAll")}</MenuItem>
            <MenuItem value="inbound">{t("emailInboxInbound")}</MenuItem>
            <MenuItem value="outbound">{t("emailInboxOutbound")}</MenuItem>
            <MenuItem value="internal">{t("emailInboxInternal")}</MenuItem>
          </Select>
        </FormControl>
        <FormControl fullWidth>
          <InputLabel id="email-link-state-label">{t("emailInboxLinkState")}</InputLabel>
          <Select labelId="email-link-state-label" value={linkState} label={t("emailInboxLinkState")} onChange={(e) => { setLinkState(String(e.target.value)); setInboxPage(1); }}>
            <MenuItem value="all">{t("emailInboxAll")}</MenuItem>
            <MenuItem value="linked">{t("emailInboxLinkedThreads")}</MenuItem>
            <MenuItem value="manual">{t("emailInboxManualOnly")}</MenuItem>
          </Select>
        </FormControl>
        <Button variant="contained" onClick={() => void load()} disabled={loading}>{loading ? t("loading") : t("refresh")}</Button>
        </Box>

      {draft ? (
        <Paper component="section" aria-labelledby="email-draft-title" variant="outlined" sx={{ p: 2, borderRadius: 3, mb: 2 }}>
          <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, flexWrap: "wrap", mb: 1.5 }}>
            <Box>
              <Typography id="email-draft-title" component="h2" variant="h6" sx={{ fontWeight: 900 }}>{t("emailInboxDraftTitle")}</Typography>
              <Typography variant="body2" sx={{ color: "text.secondary" }}>{draft.companyName} · {draft.jobTitle}</Typography>
            </Box>
            <Button onClick={() => void discardDraft()} disabled={sending}>{t("emailInboxDiscardDraft")}</Button>
          </Box>
          <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1.25 }}>
            <TextField label={t("emailInboxProvider")} value={`${draft.providerName} · ${draft.fromAddress}`} slotProps={{ input: { readOnly: true } }} />
            <TextField label={t("emailInboxThread")} value={draft.threadId || t("emailInboxNewMessage")} slotProps={{ input: { readOnly: true } }} />
            <TextField label={t("emailInboxRecipient")} type="email" value={draft.to} onChange={(event) => updateDraft({ to: event.target.value })} disabled={sending} inputProps={{ maxLength: 320 }} />
            <TextField label={t("emailInboxSubject")} value={draft.subject} onChange={(event) => updateDraft({ subject: event.target.value })} disabled={sending} inputProps={{ maxLength: 998 }} />
            <TextField label={t("emailInboxMessage")} value={draft.bodyText} onChange={(event) => updateDraft({ bodyText: event.target.value })} disabled={sending} multiline minRows={6} inputProps={{ maxLength: 200000 }} helperText={t("emailInboxCharacters", { count: draft.bodyText.length })} sx={{ gridColumn: "1 / -1" }} />
          </Box>
          {sendResult?.status === "sent" ? <Alert severity="success" sx={{ mt: 1.5 }}>{t("emailInboxSentSuccess")}</Alert> : null}
          {sendResult?.status === "uncertain" || sendResult?.status === "sending" || sendResult?.status === "pending" ? (
            <Alert severity="warning" sx={{ mt: 1.5 }}>{t("emailInboxDeliveryUncertain")}</Alert>
          ) : null}
          {sendResult?.status === "failed" ? (
            <Alert severity="error" sx={{ mt: 1.5 }} action={<Button color="inherit" size="small" onClick={() => void prepareNewAttempt()}>{t("emailInboxPrepareAttempt")}</Button>}>
              {t("emailInboxDeliveryFailed")}
            </Alert>
          ) : null}
          {draftError ? <Alert severity="warning" sx={{ mt: 1.5 }}>{draftError}</Alert> : null}
          {sendError && sendResult?.status !== "uncertain" ? <Typography variant="body2" sx={{ color: "error.main", mt: 1 }}>{sendError}</Typography> : null}
          <Box sx={{ display: "flex", justifyContent: "flex-end", gap: 1, mt: 1.5, flexWrap: "wrap" }}>
            <Button variant="outlined" onClick={() => void saveDraft()} disabled={savingDraft || sending || !!sendResult}>
              {savingDraft ? t("saving") : draft.id ? t("profileSaveChanges") : t("emailInboxSaveDraft")}
            </Button>
            <Button variant="contained" onClick={() => void sendDraft()} disabled={sending || !!sendResult || !draft.to.trim() || !draft.subject.trim() || !draft.bodyText.trim()}>
              {sending ? t("emailInboxSending") : t("emailInboxReviewSend")}
            </Button>
          </Box>
        </Paper>
      ) : null}

      {loading ? <Box sx={{ py: 6, display: "flex", justifyContent: "center" }}><CircularProgress size={28} /></Box> : null}

      {!loading && items.length === 0 ? (
        <Typography sx={{ color: "text.secondary", py: 4, textAlign: "center" }}>{t("emailInboxNoMatches")}</Typography>
      ) : null}

      <Stack spacing={1.25}>
        {items.map((item) => (
          <Paper key={item.id} variant="outlined" sx={{ p: 1.5, borderRadius: 3 }}>
            <Box sx={{ display: "flex", justifyContent: "space-between", gap: 2, flexWrap: "wrap", alignItems: "flex-start" }}>
              <Box sx={{ minWidth: 0 }}>
                <Typography sx={{ fontWeight: 800, overflowWrap: "anywhere" }}>{item.companyName || t("emailInboxUnknownCompany")} • {item.jobTitle || t("emailInboxUnknownRole")}</Typography>
                <Typography variant="body2" sx={{ color: "text.secondary", overflowWrap: "anywhere" }}>{item.subject || item.contentPreview}</Typography>
                <Typography variant="caption" sx={{ color: "text.secondary", display: "block", mt: 0.5 }}>
                  {item.externalFrom || item.from} {item.externalTo ? `→ ${item.externalTo}` : ""} · {new Date(item.date).toLocaleString(language === "nb" ? "nb-NO" : "en")}
                </Typography>
              </Box>
              <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", justifyContent: "flex-end" }}>
                {item.direction ? <Chip size="small" label={t(item.direction === "inbound" ? "emailInboxInbound" : item.direction === "outbound" ? "emailInboxOutbound" : "emailInboxInternal")} variant="outlined" /> : null}
                {item.provider ? <Chip size="small" label={item.provider === "microsoft" ? "Outlook" : item.provider === "gmail" ? "Gmail" : item.provider.toUpperCase()} variant="outlined" /> : null}
                {item.externalThreadId ? <Chip size="small" label={t("emailInboxThreadId", { id: item.externalThreadId })} color="success" variant="outlined" /> : <Chip size="small" label={t("emailInboxManualInternal")} variant="outlined" />}
                {item.labelCount > 0 ? <Chip size="small" label={t("emailInboxLabels", { count: item.labelCount })} variant="outlined" /> : null}
                {item.attachmentCount > 0 ? <Chip size="small" label={t("emailInboxAttachments", { count: item.attachmentCount })} variant="outlined" /> : null}
                <Button size="small" variant="text" onClick={() => void showMessage(item)}>{selectedMessageId === item.id ? t("emailInboxHideMessage") : t("emailInboxViewMessage")}</Button>
                <Button size="small" variant="text" onClick={() => navigate(`/jobs/${item.jobApplicationId}?section=communication`)}>{t("emailInboxOpenJob")}</Button>
                {item.provider === "gmail" && item.externalThreadId ? (
                  <Button size="small" color="warning" variant="text" disabled={unlinkingThreadId === item.externalThreadId} onClick={() => void unlinkGmailThread(item)}>
                    {unlinkingThreadId === item.externalThreadId ? t("emailInboxUnlinking") : t("emailInboxUnlinkThread")}
                  </Button>
                ) : null}
              </Box>
            </Box>
            {selectedMessageId === item.id ? (
              <Box sx={{ mt: 1.5, pt: 1.5, borderTop: "1px solid", borderColor: "divider" }}>
                {detailLoading ? <Box sx={{ display: "flex", gap: 1, alignItems: "center" }}><CircularProgress size={18} /><Typography variant="body2">{t("emailInboxLoadingMessage")}</Typography></Box> : null}
                {detailNotice ? <Alert severity="warning" sx={{ mb: 1 }}>{detailNotice}</Alert> : null}
                {detailError ? <Alert severity="error">{detailError}</Alert> : null}
                {messageDetail ? <>
                  <Typography sx={{ fontWeight: 800 }}>{messageDetail.subject || t("emailInboxNoSubject")}</Typography>
                  <Typography variant="caption" sx={{ color: "text.secondary", display: "block", mb: 1 }}>{messageDetail.from}{messageDetail.to ? ` → ${messageDetail.to}` : ""}</Typography>
                  <Typography sx={{ whiteSpace: "pre-wrap", overflowWrap: "anywhere" }}>{messageDetail.bodyText}</Typography>
                  {(messageDetail.labels.length > 0 || messageDetail.attachments.length > 0) ? <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", mt: 1 }}>
                    {messageDetail.labels.map((label, index) => <Chip key={`${label}-${index}`} size="small" label={label} variant="outlined" />)}
                    {messageDetail.attachments.map((attachment, index) => <Chip key={`${attachment.fileName || "attachment"}-${index}`} size="small" label={attachment.fileName || t("emailInboxAttachment")} variant="outlined" />)}
                  </Box> : null}
                  {item.provider && providers.find((provider) => provider.provider === item.provider)?.canSend ? (
                    <Button sx={{ mt: 1.5 }} variant="outlined" onClick={() => void startReply(item)}>{t("emailInboxReply")}</Button>
                  ) : item.provider && item.provider !== "manual" ? (
                    <Alert severity="info" sx={{ mt: 1.5 }}>{t("emailInboxReconnectToReply")}</Alert>
                  ) : null}
                </> : null}
              </Box>
            ) : null}
          </Paper>
        ))}
      </Stack>
      {inboxTotalPages > 1 ? (
        <Box sx={{ display: "flex", justifyContent: "center", mt: 2 }}>
          <Pagination
            page={inboxPage}
            count={inboxTotalPages}
            onChange={(_, value) => setInboxPage(value)}
            color="primary"
            aria-label={t("emailInboxPages")}
          />
        </Box>
      ) : null}
      </>}
    </Paper>
  );
}
