import { useCallback, useEffect, useRef, useState } from "react";
import { X, Loader2, ImagePlus, Plus, Save, Trash2 } from "lucide-react";
import { api } from "@/client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import type { ArticleDraft } from "./use-article-draft";
import type { ArticleItem } from "./article-types";

type Props = {
  channel: string;
  draft: ArticleDraft | null;
  onDraftChange: (draft: ArticleDraft) => void;
  onClearDraft: () => void;
  onClose: () => void;
  onCreated: (article: ArticleItem) => void;
};

export default function ArticleComposer({
  channel,
  draft,
  onDraftChange,
  onClearDraft,
  onClose,
  onCreated,
}: Props) {
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState("");
  const [savedAt, setSavedAt] = useState<string | null>(null);
  const draftRef = useRef(draft);

  // Sync external draft into local ref
  useEffect(() => {
    draftRef.current = draft;
  }, [draft]);

  const update = useCallback(
    (patch: Partial<ArticleDraft>) => {
      const next = { ...(draftRef.current ?? { channel, title: "", coverUrl: "", content: "", summary: "", tags: [] }), ...patch };
      draftRef.current = next;
      onDraftChange(next);
    },
    [channel, onDraftChange],
  );

  // Auto-save indicator
  const autoSaveTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
  useEffect(() => {
    if (!draft) return;
    if (autoSaveTimer.current) clearTimeout(autoSaveTimer.current);
    autoSaveTimer.current = setTimeout(() => {
      setSavedAt(new Date().toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" }));
    }, 800);
    return () => {
      if (autoSaveTimer.current) clearTimeout(autoSaveTimer.current);
    };
  }, [draft]);

  const handlePublish = useCallback(async () => {
    const cur = draftRef.current;
    if (!cur?.title?.trim()) {
      setError("Title is required");
      return;
    }
    if (!cur?.content?.trim()) {
      setError("Content is required");
      return;
    }
    setSaving(true);
    setError("");
    try {
      const res = await api.post<Record<string, unknown>>(
        `/api/v1/ws/channels/${channel}/articles`,
        {
          title: cur.title.trim(),
          cover_url: cur.coverUrl.trim() || null,
          content: cur.content.trim(),
          summary: cur.summary.trim() || null,
          tags: cur.tags.length > 0 ? cur.tags : null,
        },
      );
      onClearDraft();
      const article = res.data as unknown as ArticleItem;
      onCreated(article);
    } catch {
      setError("Failed to publish. Try again.");
    } finally {
      setSaving(false);
    }
  }, [channel, onClearDraft, onCreated]);

  if (!draft) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-start justify-center sm:items-center sm:p-4">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-background/70 backdrop-blur-sm"
        onClick={onClose}
      />

      {/* Panel */}
      <div className="relative flex max-h-full w-full flex-col overflow-hidden bg-card shadow-2xl sm:max-h-[92vh] sm:w-[min(800px,95vw)] sm:rounded-2xl sm:border sm:border-border/30">
        {/* Header */}
        <div className="flex shrink-0 items-center gap-3 border-b border-border/40 px-5 py-3">
          <Button
            className="size-8 shrink-0 cursor-pointer rounded-lg"
            onClick={onClose}
            size="icon"
            variant="ghost"
          >
            <X className="size-4" />
          </Button>
          <h2 className="flex-1 text-sm font-semibold">Write Article</h2>

          {/* Auto-save badge */}
          {savedAt && (
            <span className="inline-flex items-center gap-1 rounded-full bg-emerald-500/[0.06] px-2 py-0.5 text-[10px] font-medium text-emerald-600/60">
              <Save className="size-2.5" />
              Draft saved {savedAt}
            </span>
          )}

          {/* Discard draft */}
          <Button
            className="size-8 shrink-0 cursor-pointer rounded-lg text-muted-foreground/30 hover:text-destructive/70"
            onClick={() => {
              onClearDraft();
              setSavedAt(null);
            }}
            size="icon"
            variant="ghost"
            title="Discard draft"
          >
            <Trash2 className="size-4" />
          </Button>

          <Button
            className="h-8 cursor-pointer gap-1.5 rounded-lg"
            disabled={saving || !draft.title.trim() || !draft.content.trim()}
            onClick={handlePublish}
            size="sm"
          >
            {saving ? <Loader2 className="size-4 animate-spin" /> : null}
            Publish
          </Button>
        </div>

        {/* Body */}
        <div className="min-h-0 flex-1 space-y-5 overflow-y-auto px-5 py-4">
          {/* Title */}
          <Input
            className="border-0 bg-transparent !text-lg font-bold !shadow-none placeholder:text-muted-foreground/25 focus-visible:ring-0"
            maxLength={200}
            onChange={(e) => {
              update({ title: e.target.value });
              setError("");
            }}
            placeholder="Article title..."
            value={draft.title}
          />

          {/* Cover URL */}
          <div className="flex items-center gap-2 rounded-lg bg-muted/30 px-3 py-2">
            <ImagePlus className="size-4 shrink-0 text-muted-foreground/40" />
            <Input
              className="h-7 border-0 bg-transparent text-sm !shadow-none placeholder:text-muted-foreground/25 focus-visible:ring-0"
              onChange={(e) => update({ coverUrl: e.target.value })}
              placeholder="Cover image URL (optional)"
              value={draft.coverUrl}
            />
          </div>

          {/* Cover preview */}
          {draft.coverUrl.trim() && (
            <div className="aspect-[2/1] w-full overflow-hidden rounded-xl bg-muted/20">
              <img
                alt="Cover preview"
                className="size-full object-cover"
                src={draft.coverUrl.trim()}
                onError={(e) => {
                  (e.target as HTMLImageElement).style.display = "none";
                }}
              />
            </div>
          )}

          {/* Content */}
          <textarea
            className="min-h-[240px] w-full resize-none border-0 bg-transparent text-sm leading-relaxed placeholder:text-muted-foreground/25 focus:outline-none"
            onChange={(e) => {
              update({ content: e.target.value });
              setError("");
            }}
            placeholder="Content... Markdown supported"
            value={draft.content}
          />

          {/* Summary */}
          <Input
            className="border-0 bg-transparent text-sm !shadow-none placeholder:text-muted-foreground/25 focus-visible:ring-0"
            maxLength={300}
            onChange={(e) => update({ summary: e.target.value })}
            placeholder="Summary (optional, shown on card)"
            value={draft.summary}
          />

          {/* Tags */}
          <div>
            <div className="mb-2 flex items-center gap-2">
              <Input
                className="h-8 flex-1 bg-muted/30 text-sm placeholder:text-muted-foreground/25"
                maxLength={20}
                onKeyDown={(e) => {
                  if (e.key === "Enter") {
                    e.preventDefault();
                    const t = (e.target as HTMLInputElement).value.trim();
                    if (t && !draft.tags.includes(t) && draft.tags.length < 10) {
                      update({ tags: [...draft.tags, t] });
                      (e.target as HTMLInputElement).value = "";
                    }
                  }
                }}
                placeholder="Add tag..."
              />
              <Button
                className="h-8 cursor-pointer"
                disabled
                size="sm"
                variant="outline"
              >
                <Plus className="size-3.5" />
              </Button>
            </div>
            {draft.tags.length > 0 && (
              <div className="flex flex-wrap gap-1.5">
                {draft.tags.map((t) => (
                  <span
                    className="inline-flex cursor-pointer items-center gap-1 rounded-md bg-primary/[0.06] px-2 py-0.5 text-[11px] font-medium text-primary/60 transition-colors hover:bg-destructive/[0.08] hover:text-destructive/60"
                    key={t}
                    onClick={() =>
                      update({ tags: draft.tags.filter((x) => x !== t) })
                    }
                  >
                    {t}
                    <X className="size-3" />
                  </span>
                ))}
              </div>
            )}
          </div>

          {error && (
            <div className="rounded-lg bg-destructive/[0.04] px-3 py-2">
              <p className="text-[13px] text-destructive/80">{error}</p>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
