import { useEffect, useState } from "react";
import { API_BASE } from "../../config";
import { MailAccounts } from "./MailAccounts";

const inputStyle = { padding: "0.6rem", background: "#222", color: "#eee", border: "1px solid #333", borderRadius: "8px", width: "100%", boxSizing: "border-box" };
const btn = (bg) => ({ padding: "0.5rem 1rem", background: bg, color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer" });

const accountLabel = (a) => a.label || a.from_addr || a.username || "(unnamed)";

export function Mail() {
  const [accounts, setAccounts] = useState(null);        // null until loaded
  const [expanded, setExpanded] = useState({});           // {accountId: bool}
  const [foldersByAccount, setFoldersByAccount] = useState({}); // {accountId: [folders]}
  const [selection, setSelection] = useState(null);       // {accountId, folder}
  const [messages, setMessages] = useState([]);
  const [selected, setSelected] = useState(null);         // full message
  const [composing, setComposing] = useState(null);       // {accountId,to,cc,subject,body}
  const [busy, setBusy] = useState(false);
  const [note, setNote] = useState("");
  const [showAccounts, setShowAccounts] = useState(false);

  const loadFoldersFor = async (accountId) => {
    const r = await fetch(`${API_BASE}/mail/folders?account_id=${encodeURIComponent(accountId)}`);
    const folders = r.ok ? (await r.json()).folders || [] : [];
    setFoldersByAccount(prev => ({ ...prev, [accountId]: folders }));
    return folders;
  };

  const loadMessages = async (sel = selection) => {
    if (!sel) return;
    setBusy(true); setSelected(null);
    try {
      const r = await fetch(`${API_BASE}/mail/messages?account_id=${encodeURIComponent(sel.accountId)}&folder=${encodeURIComponent(sel.folder)}&limit=40`);
      const data = r.ok ? await r.json() : null;
      setMessages(data ? data.messages || [] : []);
      if (!r.ok) setNote((await r.json().catch(() => ({}))).detail || "Failed to load messages.");
    } finally { setBusy(false); }
  };

  const bootstrap = async () => {
    const r = await fetch(`${API_BASE}/mail/accounts`);
    const list = r.ok ? (await r.json()).accounts || [] : [];
    setAccounts(list);
    const configured = list.filter(a => a.configured);
    setExpanded(Object.fromEntries(list.map(a => [a.id, true])));
    await Promise.all(configured.map(a => loadFoldersFor(a.id)));
    if (configured.length) {
      const sel = { accountId: configured[0].id, folder: "INBOX" };
      setSelection(sel);
      loadMessages(sel);
    }
  };

  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => { bootstrap(); }, []);

  const onAccountsChanged = async (list) => {
    setAccounts(list);
    setExpanded(prev => ({ ...Object.fromEntries(list.map(a => [a.id, true])), ...prev }));
    const configured = list.filter(a => a.configured);
    await Promise.all(configured.map(a => loadFoldersFor(a.id)));
    // if the active selection's account vanished, fall back to the first configured one
    if (selection && !configured.some(a => a.id === selection.accountId)) {
      if (configured.length) {
        const sel = { accountId: configured[0].id, folder: "INBOX" };
        setSelection(sel);
        loadMessages(sel);
      } else {
        setSelection(null); setMessages([]); setSelected(null);
      }
    } else if (!selection && configured.length) {
      const sel = { accountId: configured[0].id, folder: "INBOX" };
      setSelection(sel);
      loadMessages(sel);
    }
  };

  const openMessage = async (m) => {
    setBusy(true);
    try {
      const r = await fetch(`${API_BASE}/mail/message?account_id=${encodeURIComponent(selection.accountId)}&folder=${encodeURIComponent(selection.folder)}&uid=${encodeURIComponent(m.uid)}`);
      if (r.ok) { setSelected(await r.json()); setMessages(prev => prev.map(x => x.uid === m.uid ? { ...x, seen: true } : x)); }
    } finally { setBusy(false); }
  };

  const deleteMessage = async (m) => {
    if (!window.confirm("Delete this message?")) return;
    await fetch(`${API_BASE}/mail/delete`, {
      method: "POST", headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ account_id: selection.accountId, folder: selection.folder, uid: m.uid }),
    });
    setSelected(null); loadMessages();
  };

  const sendCompose = async () => {
    setBusy(true); setNote("Sending…");
    try {
      const r = await fetch(`${API_BASE}/mail/send`, {
        method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(composing),
      });
      const d = await r.json().catch(() => ({}));
      if (r.ok) { setNote(`Sent to ${(d.to || []).join(", ")}.`); setComposing(null); }
      else setNote(d.detail || "Send failed.");
    } finally { setBusy(false); }
  };

  const startCompose = () => setComposing({
    accountId: (selection && selection.accountId) || (accounts || []).find(a => a.configured)?.id || "",
    to: "", cc: "", subject: "", body: "",
  });

  const reply = (m) => setComposing({
    accountId: selection.accountId,
    to: m.from, cc: "", subject: /^re:/i.test(m.subject || "") ? m.subject : `Re: ${m.subject || ""}`,
    body: `\n\n---\nOn ${m.date ? new Date(m.date).toLocaleString() : ""}, ${m.from} wrote:\n${(m.text || "").slice(0, 2000)}`,
  });

  const selectFolder = (accountId, folder) => {
    const sel = { accountId, folder };
    setSelection(sel);
    loadMessages(sel);
  };

  const toggleExpanded = (accountId) => setExpanded(prev => ({ ...prev, [accountId]: !prev[accountId] }));

  const configuredAccounts = (accounts || []).filter(a => a.configured);

  if (accounts === null) return <div style={{ padding: "1.5rem", color: "#888" }}>Loading…</div>;

  // ---- empty state: no configured accounts yet ----
  if (configuredAccounts.length === 0) {
    return (
      <div style={{ padding: "1.5rem", color: "#eee", maxWidth: "560px" }}>
        <h2 style={{ marginTop: 0 }}>✉️ Mail</h2>
        <p style={{ color: "#aaa" }}>No mail accounts configured yet.</p>
        <button onClick={() => setShowAccounts(true)} style={btn("#007acc")}>+ Add mail account</button>
        {showAccounts && <MailAccounts onClose={() => setShowAccounts(false)} onChanged={onAccountsChanged} />}
      </div>
    );
  }

  // ---- client ----
  return (
    <div style={{ display: "flex", height: "100%", color: "#eee" }}>
      <div style={{ width: "200px", borderRight: "1px solid #2a2a2a", padding: "0.75rem", overflowY: "auto", flexShrink: 0, display: "flex", flexDirection: "column" }}>
        <div style={{ display: "flex", gap: "0.4rem", marginBottom: "0.75rem" }}>
          <button onClick={startCompose} style={{ ...btn("#007acc"), flexGrow: 1 }}>✎ Compose</button>
          <button onClick={() => setShowAccounts(true)} title="Manage accounts"
            style={{ ...btn("transparent"), border: "1px solid #444", color: "#ccc", padding: "0.5rem 0.6rem" }}>⚙</button>
        </div>

        <div style={{ flexGrow: 1, overflowY: "auto" }}>
          {(accounts || []).map(a => (
            <div key={a.id} style={{ marginBottom: "0.5rem" }}>
              <div onClick={() => toggleExpanded(a.id)}
                style={{ display: "flex", alignItems: "center", gap: "0.35rem", padding: "0.3rem 0.3rem", cursor: "pointer", color: a.configured ? "#ddd" : "#c9a227", fontSize: "0.82rem", fontWeight: 600 }}>
                <span style={{ display: "inline-block", width: "0.8em", transform: expanded[a.id] ? "rotate(90deg)" : "none", transition: "transform 0.1s" }}>▸</span>
                <span style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{accountLabel(a)}</span>
              </div>
              {expanded[a.id] && (
                !a.configured ? (
                  <div style={{ padding: "0.2rem 0.5rem 0.2rem 1.4rem", fontSize: "0.75rem", color: "#c9a227" }}>needs password — ⚙ to fix</div>
                ) : (foldersByAccount[a.id] || []).map(f => {
                  const isActive = selection && selection.accountId === a.id && selection.folder === f;
                  return (
                    <div key={f} onClick={() => selectFolder(a.id, f)}
                      style={{ padding: "0.32rem 0.5rem 0.32rem 1.4rem", borderRadius: "6px", cursor: "pointer", fontSize: "0.8rem", background: isActive ? "#1c2a3a" : "transparent", color: isActive ? "#fff" : "#aaa", marginBottom: "0.1rem", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                      {f}
                    </div>
                  );
                })
              )}
            </div>
          ))}
        </div>
      </div>

      <div style={{ width: "320px", borderRight: "1px solid #2a2a2a", overflowY: "auto", flexShrink: 0 }}>
        <div style={{ padding: "0.5rem 0.75rem", display: "flex", justifyContent: "space-between", alignItems: "center", borderBottom: "1px solid #2a2a2a" }}>
          <span style={{ fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
            {selection ? selection.folder : "—"}
          </span>
          <button onClick={() => loadMessages()} disabled={!selection} style={{ background: "none", border: "none", color: "#888", cursor: "pointer" }}>⟳</button>
        </div>
        {!selection ? <div style={{ padding: "1rem", color: "#777" }}>Select a folder.</div>
          : busy && messages.length === 0 ? <div style={{ padding: "1rem", color: "#777" }}>Loading…</div>
          : messages.length === 0 ? <div style={{ padding: "1rem", color: "#777" }}>{note || "No messages."}</div>
            : messages.map(m => (
              <div key={m.uid} onClick={() => openMessage(m)}
                style={{ padding: "0.6rem 0.75rem", borderBottom: "1px solid #1e1e1e", cursor: "pointer", background: selected && selected.uid === m.uid ? "#1c2a3a" : "transparent" }}>
                <div style={{ fontSize: "0.8rem", color: m.seen ? "#999" : "#fff", fontWeight: m.seen ? 400 : 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{m.from}</div>
                <div style={{ fontSize: "0.82rem", color: m.seen ? "#aaa" : "#eee", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{m.subject || "(no subject)"}</div>
                <div style={{ fontSize: "0.72rem", color: "#666", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{m.preview}</div>
              </div>
            ))}
      </div>

      <div style={{ flexGrow: 1, overflowY: "auto", padding: "1rem", minWidth: 0 }}>
        {composing ? (
          <div style={{ display: "flex", flexDirection: "column", gap: "0.6rem", maxWidth: "640px" }}>
            <h3 style={{ margin: 0 }}>New message</h3>
            {configuredAccounts.length > 1 && (
              <div>
                <label style={{ display: "block", fontSize: "0.75rem", color: "#888", marginBottom: "0.3rem" }}>From</label>
                <select value={composing.accountId} onChange={e => setComposing({ ...composing, accountId: e.target.value })}
                  style={{ ...inputStyle, width: "100%" }}>
                  {configuredAccounts.map(a => <option key={a.id} value={a.id}>{accountLabel(a)} — {a.from_addr || a.username}</option>)}
                </select>
              </div>
            )}
            <input placeholder="To" value={composing.to} onChange={e => setComposing({ ...composing, to: e.target.value })} style={inputStyle} />
            <input placeholder="Cc" value={composing.cc} onChange={e => setComposing({ ...composing, cc: e.target.value })} style={inputStyle} />
            <input placeholder="Subject" value={composing.subject} onChange={e => setComposing({ ...composing, subject: e.target.value })} style={inputStyle} />
            <textarea rows={14} placeholder="Body" value={composing.body} onChange={e => setComposing({ ...composing, body: e.target.value })} style={inputStyle} />
            <div style={{ display: "flex", gap: "0.6rem", alignItems: "center" }}>
              <button onClick={sendCompose} disabled={busy || !composing.to.trim()} style={btn(busy || !composing.to.trim() ? "#555" : "#007acc")}>Send</button>
              <button onClick={() => setComposing(null)} style={{ ...btn("transparent"), border: "1px solid #444", color: "#ccc" }}>Cancel</button>
              <span style={{ color: "#8ab4ff", fontSize: "0.85rem" }}>{note}</span>
            </div>
          </div>
        ) : selected ? (
          <div>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: "1rem" }}>
              <h3 style={{ margin: "0 0 0.5rem" }}>{selected.subject || "(no subject)"}</h3>
              <div style={{ display: "flex", gap: "0.4rem", flexShrink: 0 }}>
                <button onClick={() => reply(selected)} style={btn("#2a4a6a")}>Reply</button>
                <button onClick={() => deleteMessage(selected)} style={{ ...btn("#3a1a1a"), color: "#ff8a80" }}>Delete</button>
              </div>
            </div>
            <div style={{ color: "#aaa", fontSize: "0.85rem", marginBottom: "0.75rem" }}>
              <div><b>From:</b> {selected.from}</div>
              <div><b>To:</b> {(selected.to || []).join(", ")}</div>
              {selected.date && <div>{new Date(selected.date).toLocaleString()}</div>}
            </div>
            {/* Sandboxed iframe: no scripts, no same-origin — email HTML can't touch the app. */}
            {selected.html
              ? <iframe title="message" sandbox="" srcDoc={selected.html} style={{ width: "100%", height: "60vh", border: "1px solid #2a2a2a", borderRadius: "8px", background: "#fff" }} />
              : <pre style={{ whiteSpace: "pre-wrap", fontFamily: "system-ui", color: "#ddd" }}>{selected.text || "(empty)"}</pre>}
            {selected.attachments && selected.attachments.length > 0 && (
              <div style={{ marginTop: "0.75rem", color: "#888", fontSize: "0.8rem" }}>
                📎 {selected.attachments.map(a => a.name).join(", ")}
              </div>
            )}
          </div>
        ) : (
          <div style={{ color: "#777", paddingTop: "2rem", textAlign: "center" }}>Select a message.</div>
        )}
      </div>

      {showAccounts && <MailAccounts onClose={() => setShowAccounts(false)} onChanged={onAccountsChanged} />}
    </div>
  );
}
