import { useCallback, useEffect, useRef, useState } from "react";

const DRAFT_KEY = "article-composer-draft";

export type ArticleDraft = {
  channel: string;
  title: string;
  coverUrl: string;
  content: string;
  summary: string;
  tags: string[];
};

function loadDraft(): ArticleDraft | null {
  try {
    const raw = localStorage.getItem(DRAFT_KEY);
    if (!raw) return null;
    const parsed = JSON.parse(raw) as ArticleDraft;
    if (!parsed.channel || (!parsed.title && !parsed.content)) return null;
    return parsed;
  } catch {
    return null;
  }
}

function saveDraft(draft: ArticleDraft | null) {
  if (!draft) {
    localStorage.removeItem(DRAFT_KEY);
    return;
  }
  try {
    localStorage.setItem(DRAFT_KEY, JSON.stringify(draft));
  } catch {
    // Storage full or unavailable — silently drop
  }
}

export function useArticleDraft(defaultChannel?: string) {
  const [draft, setDraftState] = useState<ArticleDraft | null>(() => loadDraft());
  const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
  const draftRef = useRef(draft);

  // Debounced persist
  const persist = useCallback((next: ArticleDraft | null) => {
    if (timerRef.current) clearTimeout(timerRef.current);
    setDraftState(next);
    timerRef.current = setTimeout(() => {
      saveDraft(next);
    }, 500);
  }, []);

  // Keep ref in sync — only for unmount flush
  useEffect(() => {
    draftRef.current = draft;
  }, [draft]);

  // Flush on unmount
  useEffect(() => {
    return () => {
      if (timerRef.current) clearTimeout(timerRef.current);
      saveDraft(draftRef.current);
    };
  }, []);

  const initDraft = useCallback(
    (channel: string) => {
      const existing = loadDraft();
      if (existing && existing.channel === channel) {
        setDraftState(existing);
        return existing;
      }
      const fresh: ArticleDraft = {
        channel,
        title: "",
        coverUrl: "",
        content: "",
        summary: "",
        tags: [],
      };
      setDraftState(fresh);
      saveDraft(null);
      return fresh;
    },
    [],
  );

  const clearDraft = useCallback(() => {
    setDraftState(null);
    saveDraft(null);
  }, []);

  // Load draft on mount if channel matches
  useEffect(() => {
    if (defaultChannel) {
      const existing = loadDraft();
      if (!existing || existing.channel !== defaultChannel) {
        // eslint-disable-next-line react-hooks/set-state-in-effect -- sync on mount
        setDraftState(null);
      } else {
        setDraftState(existing);
      }
    }
  }, [defaultChannel]);

  return {
    draft,
    persist,
    initDraft,
    clearDraft,
  };
}
