import { useEffect, useMemo, useState } from "react";
import type { DeckAccount, DeckColumn, DeckListsCache } from "../types/app";
import type { TwitterList } from "../lib/fetching/types";

interface AddColumnModalProps {
  accounts: DeckAccount[];
  isOpen: boolean;
  onClose: () => void;
  onAdd: (column: Omit<DeckColumn, "id">) => void;
  activeAccountId?: string;
  fetchLists: (accountId: string) => Promise<TwitterList[]>;
  listsCache: DeckListsCache;
}

const columnOptions = [
  {
    id: "foryou",
    label: "For You",
    description: "Twitter's AI-ranked firehose",
  },
  {
    id: "following",
    label: "Following",
    description: "Chronological feed of people you follow",
  },
  { id: "bookmarks", label: "Bookmarks", description: "Your saved deep dives" },
  { id: "list", label: "List", description: "Curate a topic-specific stream" },
  { id: "chat", label: "Chat", description: "Mentions & notifications" },
] as const;

export function AddColumnModal({
  accounts,
  activeAccountId,
  isOpen,
  onClose,
  onAdd,
  fetchLists,
  listsCache,
}: AddColumnModalProps) {
  const [kind, setKind] = useState<DeckColumn["kind"]>("foryou");
  const [accountId, setAccountId] = useState<string>(
    activeAccountId || accounts[0]?.id || "",
  );
  const [title, setTitle] = useState("For You");
  const [listId, setListId] = useState<string>("");
  const [listOptions, setListOptions] = useState<TwitterList[]>([]);
  const [listsLoading, setListsLoading] = useState(false);
  const [listsError, setListsError] = useState<string | undefined>();

  useEffect(() => {
    if (!isOpen) return;
    setAccountId(activeAccountId || accounts[0]?.id || "");
  }, [isOpen, activeAccountId, accounts]);

  useEffect(() => {
    setTitle(defaultTitle(kind));
  }, [kind]);

  useEffect(() => {
    if (!isOpen || kind !== "list" || !accountId) return;
    let mounted = true;
    async function loadLists() {
      try {
        setListsLoading(true);
        setListsError(undefined);
        const cached = listsCache[accountId];
        if (cached) {
          setListOptions(cached);
          return;
        }
        const lists = await fetchLists(accountId);
        if (!mounted) return;
        setListOptions(lists);
      } catch (error) {
        setListsError(
          error instanceof Error ? error.message : "Failed to load lists",
        );
      } finally {
        if (mounted) setListsLoading(false);
      }
    }
    loadLists();
    return () => {
      mounted = false;
    };
  }, [accountId, fetchLists, isOpen, kind, listsCache]);

  useEffect(() => {
    if (!isOpen) return;
    setListId("");
    setListOptions([]);
  }, [accountId, isOpen, kind]);

  const selectedAccount = useMemo(
    () => accounts.find((account) => account.id === accountId),
    [accountId, accounts],
  );

  const canSubmit = Boolean(selectedAccount && (kind !== "list" || listId));

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    if (!canSubmit || !selectedAccount) return;
    onAdd({
      accountId: selectedAccount.id,
      account: selectedAccount.username || "",
      kind,
      title: title.trim() || defaultTitle(kind),
      listId: listId || undefined,
      listName:
        kind === "list"
          ? listOptions.find((list) => list.id === listId)?.name
          : undefined,
    });
    onClose();
  };

  useEffect(() => {
    if (!isOpen) return;
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape") onClose();
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [isOpen, onClose]);

  if (!isOpen) return null;

  return (
    <div
      className="modal-backdrop"
      role="dialog"
      aria-modal="true"
      onMouseDown={(event) => {
        if (event.target === event.currentTarget) {
          onClose();
        }
      }}
    >
      <div className="modal">
        <header>
          <div>
            <p className="eyebrow">New column</p>
            <h2>Design your stream</h2>
          </div>
          <button
            className="ghost"
            onClick={onClose}
            aria-label="Close add column modal"
          >
            ×
          </button>
        </header>
        <form onSubmit={handleSubmit} className="modal-body">
          <label>
            Account
            <select
              value={accountId}
              onChange={(e) => setAccountId(e.target.value)}
            >
              {accounts.map((account) => (
                <option value={account.id} key={account.id}>
                  {account.label}
                  {account.handle ? ` (@${account.handle})` : ""}
                </option>
              ))}
            </select>
          </label>
          <div className="option-grid">
            {columnOptions.map((option) => (
              <button
                type="button"
                key={option.id}
                className={`option ${kind === option.id ? "selected" : ""}`}
                onClick={() => setKind(option.id)}
              >
                <div>
                  <strong>{option.label}</strong>
                  <p>{option.description}</p>
                </div>
              </button>
            ))}
          </div>
          {kind === "list" && (
            <label>
              Choose a list
              {listsError && <span className="error">{listsError}</span>}
              <select
                value={listId}
                disabled={listsLoading}
                onChange={(e) => setListId(e.target.value)}
              >
                <option value="" disabled>
                  {listsLoading ? "Loading lists..." : "Select a list"}
                </option>
                {listOptions.map((list) => (
                  <option key={list.id} value={list.id}>
                    {list.name} ({list.member_count})
                  </option>
                ))}
              </select>
            </label>
          )}
          <label>
            Column title
            <input
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="Custom title"
            />
          </label>
          <button className="primary" type="submit" disabled={!canSubmit}>
            Add column
          </button>
        </form>
      </div>
    </div>
  );
}

function defaultTitle(kind: DeckColumn["kind"]) {
  switch (kind) {
    case "following":
      return "Following";
    case "bookmarks":
      return "Bookmarks";
    case "list":
      return "List";
    case "chat":
      return "Chat";
    default:
      return "For You";
  }
}
