import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import {
  Box,
  Alert,
  Chip,
  CircularProgress,
  FormControl,
  InputLabel,
  MenuItem,
  Paper,
  Select,
  Stack,
  TextField,
  Typography,
  Button,
} from "@mui/material";
import MailOutlineIcon from "@mui/icons-material/MailOutline";
import { api, getApiErrorMessage } from "../api";
import { useToast } from "../toast";
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 EmailProviderStatus = {
  provider: string;
  displayName: string;
  connected: boolean;
  address?: string | null;
  canRead: boolean;
  canSend: boolean;
};

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 }>;
};

export default function CorrespondenceInboxPage() {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const view = searchParams.get("view") === "review" ? "review" : "inbox";
  const { toast } = useToast();
  const [items, setItems] = useState<CorrespondenceInboxItem[]>([]);
  const [providers, setProviders] = useState<EmailProviderStatus[]>([]);
  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 load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await api.get<CorrespondenceInboxItem[]>("/correspondence", {
        params: {
          q: query.trim() || undefined,
          direction: direction === "all" ? undefined : direction,
          linkState: linkState === "all" ? undefined : linkState,
        },
      });
      setItems(res.data ?? []);
    } catch (error) {
      toast(getApiErrorMessage(error, "Failed to load correspondence inbox."), "error");
    } finally {
      setLoading(false);
    }
  }, [direction, linkState, query, toast]);

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

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

  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 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("The provider copy is unavailable. Showing the saved JobTracker copy.");
        }
      }

      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, "Failed to load this message."));
    } finally {
      if (request === detailRequest.current) setDetailLoading(false);
    }
  };

  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 }}>Job email</Typography>
          <Typography variant="body2" sx={{ color: "text.secondary" }}>
            Review linked correspondence and suggested recruitment messages in one place.
          </Typography>
        </Box>
        <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", alignItems: "center" }}>
          {view === "inbox" ? <Chip icon={<MailOutlineIcon />} label={`${items.length} items`} variant="outlined" /> : null}
          {view === "inbox" ? <Chip label={`${filteredSummary.linked} linked`} variant="outlined" color={filteredSummary.linked > 0 ? "success" : "default"} /> : null}
          {view === "inbox" ? <Chip label={`${filteredSummary.inbound} inbound`} variant="outlined" /> : null}
          <Button variant={view === "inbox" ? "contained" : "text"} size="small" onClick={() => setSearchParams({})}>Linked messages</Button>
          <Button variant={view === "review" ? "contained" : "text"} size="small" onClick={() => setSearchParams({ view: "review" })}>Review suggestions</Button>
        </Box>
      </Box>

      <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", mb: 2 }} aria-label="Email provider status">
        {providers.map((provider) => (
          <Chip
            key={provider.provider}
            size="small"
            color={provider.connected ? "success" : "default"}
            variant="outlined"
            label={`${provider.displayName}: ${provider.connected ? provider.address || "Connected" : "Not connected"}${provider.canSend ? " · Send enabled" : " · Read only"}`}
          />
        ))}
      </Box>

      {view === "review" ? <GmailReviewPage embedded /> : <>
        <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "2fr 1fr 1fr auto" }, gap: 1.25, mb: 2 }}>
        <TextField label="Search" value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Company, role, recruiter, subject" />
        <FormControl fullWidth>
          <InputLabel>Direction</InputLabel>
          <Select value={direction} label="Direction" onChange={(e) => setDirection(String(e.target.value))}>
            <MenuItem value="all">All</MenuItem>
            <MenuItem value="inbound">Inbound</MenuItem>
            <MenuItem value="outbound">Outbound</MenuItem>
            <MenuItem value="internal">Internal</MenuItem>
          </Select>
        </FormControl>
        <FormControl fullWidth>
          <InputLabel>Link state</InputLabel>
          <Select value={linkState} label="Link state" onChange={(e) => setLinkState(String(e.target.value))}>
            <MenuItem value="all">All</MenuItem>
            <MenuItem value="linked">Linked threads</MenuItem>
            <MenuItem value="manual">Manual/internal only</MenuItem>
          </Select>
        </FormControl>
        <Button variant="contained" onClick={() => void load()} disabled={loading}>{loading ? "Loading..." : "Refresh"}</Button>
        </Box>

      {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" }}>No correspondence matches the current filters.</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 || "Unknown company"} • {item.jobTitle || "Unknown role"}</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()}
                </Typography>
              </Box>
              <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", justifyContent: "flex-end" }}>
                {item.direction ? <Chip size="small" label={item.direction} 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={`Thread ${item.externalThreadId}`} color="success" variant="outlined" /> : <Chip size="small" label="Manual/internal" variant="outlined" />}
                {item.labelCount > 0 ? <Chip size="small" label={`${item.labelCount} labels`} variant="outlined" /> : null}
                {item.attachmentCount > 0 ? <Chip size="small" label={`${item.attachmentCount} attachments`} variant="outlined" /> : null}
                <Button size="small" variant="text" onClick={() => void showMessage(item)}>{selectedMessageId === item.id ? "Hide message" : "View message"}</Button>
                <Button size="small" variant="text" onClick={() => navigate(`/jobs?open=${item.jobApplicationId}`)}>Open job</Button>
              </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">Loading message…</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 || "No subject"}</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 || "Attachment"} variant="outlined" />)}
                  </Box> : null}
                </> : null}
              </Box>
            ) : null}
          </Paper>
        ))}
      </Stack>
      </>}
    </Paper>
  );
}
