"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import Image from "next/image";
import { Send, FileText, Clock, CheckCircle, XCircle, Plus, User, Loader2, AtSign, Radio, Trash2, Download, Eye, Pencil } from "lucide-react";
import { useAuth } from "@/hooks/useAuth";
import { api } from "@/lib/api";
import { shortenPubkey, fetchEventFromRelays, fetchLongformFromRelays } from "@/lib/nostr";
import { formatDate } from "@/lib/utils";
import { Button } from "@/components/ui/Button";

interface Submission {
  id: string;
  eventId?: string;
  naddr?: string;
  title: string;
  status: string;
  reviewNote?: string;
  createdAt: string;
}

const STATUS_CONFIG: Record<string, { label: string; icon: typeof Clock; className: string }> = {
  PENDING: {
    label: "Pending Review",
    icon: Clock,
    className: "text-primary bg-primary/10",
  },
  APPROVED: {
    label: "Approved",
    icon: CheckCircle,
    className: "text-green-400 bg-green-400/10",
  },
  REJECTED: {
    label: "Rejected",
    icon: XCircle,
    className: "text-error bg-error/10",
  },
};

interface UserRelay {
  id: string;
  url: string;
  read: boolean;
  write: boolean;
  createdAt: string;
}

type Tab = "submissions" | "profile" | "relays";

type UsernameStatus =
  | { state: "idle" }
  | { state: "checking" }
  | { state: "available" }
  | { state: "unavailable"; reason: string };

export default function DashboardPage() {
  const { user, login } = useAuth();
  const [activeTab, setActiveTab] = useState<Tab>("submissions");

  // Submissions state
  const [submissions, setSubmissions] = useState<Submission[]>([]);
  const [loadingSubs, setLoadingSubs] = useState(true);
  const [showForm, setShowForm] = useState(false);
  const [noteInput, setNoteInput] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [formError, setFormError] = useState("");
  const [formSuccess, setFormSuccess] = useState("");

  // Profile state
  const [username, setUsername] = useState("");
  const [usernameStatus, setUsernameStatus] = useState<UsernameStatus>({ state: "idle" });
  const [saving, setSaving] = useState(false);
  const [saveError, setSaveError] = useState("");
  const [saveSuccess, setSaveSuccess] = useState("");
  const [hostname, setHostname] = useState("");
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  // Relay state
  const [userRelays, setUserRelays] = useState<UserRelay[]>([]);
  const [loadingRelays, setLoadingRelays] = useState(true);
  const [newRelayUrl, setNewRelayUrl] = useState("");
  const [addingRelay, setAddingRelay] = useState(false);
  const [importingNip65, setImportingNip65] = useState(false);
  const [relayError, setRelayError] = useState("");
  const [relaySuccess, setRelaySuccess] = useState("");

  const displayName = user?.name || user?.displayName || shortenPubkey(user?.pubkey || "");

  useEffect(() => {
    setHostname(window.location.hostname);
  }, []);

  useEffect(() => {
    if (user?.username) {
      setUsername(user.username);
    }
  }, [user?.username]);

  const loadSubmissions = useCallback(async () => {
    try {
      const data = await api.getMySubmissions();
      setSubmissions(data);
    } catch {
      // Silently handle
    } finally {
      setLoadingSubs(false);
    }
  }, []);

  const loadRelays = useCallback(async () => {
    try {
      const data = await api.getUserRelays();
      setUserRelays(data);
    } catch {
      // Silently handle
    } finally {
      setLoadingRelays(false);
    }
  }, []);

  useEffect(() => {
    loadSubmissions();
    loadRelays();
  }, [loadSubmissions, loadRelays]);

  const extractTitle = (event: any): string => {
    const titleTag = event?.tags?.find((t: string[]) => t[0] === "title");
    return titleTag?.[1]?.trim() || "Untitled";
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setFormError("");
    setFormSuccess("");

    const input = noteInput.trim();
    if (!input) {
      setFormError("A Note ID or naddr is required");
      return;
    }

    setSubmitting(true);
    try {
      let payload: { title: string; eventId?: string; naddr?: string };

      if (input.startsWith("naddr1")) {
        const event = await fetchLongformFromRelays(input);
        if (!event) {
          throw new Error("Could not find that article on the relays");
        }
        payload = { title: extractTitle(event), naddr: input };
      } else {
        let hexId = input;
        if (input.startsWith("note1")) {
          try {
            const { nip19 } = await import("nostr-tools");
            const decoded = nip19.decode(input);
            if (decoded.type !== "note") throw new Error();
            hexId = decoded.data as string;
          } catch {
            throw new Error("Invalid note id");
          }
        } else if (!/^[0-9a-f]{64}$/i.test(input)) {
          throw new Error("Enter a valid note id, naddr, or hex event id");
        }
        const event = await fetchEventFromRelays(hexId);
        if (!event) {
          throw new Error("Could not find that note on the relays");
        }
        payload = { title: extractTitle(event), eventId: hexId };
      }

      await api.createSubmission(payload);
      setFormSuccess(`Submission "${payload.title}" sent for review!`);
      setNoteInput("");
      setShowForm(false);
      await loadSubmissions();
    } catch (err: any) {
      setFormError(err.message || "Failed to submit");
    } finally {
      setSubmitting(false);
    }
  };

  const handleAddRelay = async (e: React.FormEvent) => {
    e.preventDefault();
    setRelayError("");
    setRelaySuccess("");

    const url = newRelayUrl.trim();
    if (!url) {
      setRelayError("Relay URL is required");
      return;
    }
    if (!url.startsWith("wss://") && !url.startsWith("ws://")) {
      setRelayError("URL must start with wss:// or ws://");
      return;
    }

    setAddingRelay(true);
    try {
      await api.addUserRelay({ url });
      setNewRelayUrl("");
      setRelaySuccess("Relay added");
      await loadRelays();
    } catch (err: any) {
      setRelayError(err.message || "Failed to add relay");
    } finally {
      setAddingRelay(false);
    }
  };

  const handleRemoveRelay = async (id: string) => {
    setRelayError("");
    try {
      await api.removeUserRelay(id);
      setUserRelays((prev) => prev.filter((r) => r.id !== id));
    } catch (err: any) {
      setRelayError(err.message || "Failed to remove relay");
    }
  };

  const handleImportNip65 = async () => {
    setRelayError("");
    setRelaySuccess("");
    setImportingNip65(true);
    try {
      const result = await api.importNip65Relays();
      if (result.imported > 0) {
        setRelaySuccess(`Imported ${result.imported} relay(s) from your NIP-65 list`);
        await loadRelays();
      } else {
        setRelayError(result.message || "No NIP-65 relay list found for your pubkey");
      }
    } catch (err: any) {
      setRelayError(err.message || "Failed to import NIP-65 relays");
    } finally {
      setImportingNip65(false);
    }
  };

  const handleUsernameChange = (value: string) => {
    setUsername(value);
    setSaveError("");
    setSaveSuccess("");

    if (debounceRef.current) clearTimeout(debounceRef.current);

    const trimmed = value.trim().toLowerCase();

    if (!trimmed || trimmed === (user?.username ?? "")) {
      setUsernameStatus({ state: "idle" });
      return;
    }

    setUsernameStatus({ state: "checking" });

    debounceRef.current = setTimeout(async () => {
      try {
        const result = await api.checkUsername(trimmed);
        if (result.available) {
          setUsernameStatus({ state: "available" });
        } else {
          setUsernameStatus({ state: "unavailable", reason: result.reason || "Username is not available" });
        }
      } catch {
        setUsernameStatus({ state: "unavailable", reason: "Could not check availability" });
      }
    }, 500);
  };

  const handleSaveProfile = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaveError("");
    setSaveSuccess("");

    const trimmed = username.trim().toLowerCase();
    if (!trimmed) {
      setSaveError("Username is required");
      return;
    }

    setSaving(true);
    try {
      const updated = await api.updateProfile({ username: trimmed });
      setSaveSuccess(`Username saved! Your NIP-05 address is ${updated.username}@${hostname}`);
      setUsernameStatus({ state: "idle" });
      // Persist updated username into stored user
      const stored = localStorage.getItem("bbe_user");
      if (stored) {
        try {
          const parsed = JSON.parse(stored);
          localStorage.setItem("bbe_user", JSON.stringify({ ...parsed, username: updated.username }));
        } catch {
          // ignore
        }
      }
    } catch (err: any) {
      setSaveError(err.message || "Failed to save username");
    } finally {
      setSaving(false);
    }
  };

  const isSaveDisabled =
    saving ||
    usernameStatus.state === "checking" ||
    usernameStatus.state === "unavailable" ||
    !username.trim();

  return (
    <div>
      <div className="flex items-center gap-5 mb-12">
        {user?.picture ? (
          <Image
            src={user.picture}
            alt={displayName}
            width={56}
            height={56}
            className="rounded-full object-cover"
            style={{ width: 56, height: 56 }}
            unoptimized
          />
        ) : (
          <div className="w-14 h-14 rounded-full bg-surface-container-high flex items-center justify-center text-on-surface font-bold text-xl">
            {(displayName)[0]?.toUpperCase() || "?"}
          </div>
        )}
        <div>
          <h1 className="text-2xl font-bold text-on-surface">{displayName}</h1>
          <p className="text-on-surface-variant text-sm">Your Dashboard</p>
        </div>
      </div>

      {/* Tabs */}
      <div className="flex gap-1 mb-8 border-b border-outline-variant">
        <button
          onClick={() => setActiveTab("submissions")}
          className={`flex items-center gap-2 px-4 py-3 text-sm font-semibold border-b-2 transition-colors ${
            activeTab === "submissions"
              ? "border-primary text-primary"
              : "border-transparent text-on-surface-variant hover:text-on-surface"
          }`}
        >
          <FileText size={16} />
          Submissions
        </button>
        <button
          onClick={() => setActiveTab("profile")}
          className={`flex items-center gap-2 px-4 py-3 text-sm font-semibold border-b-2 transition-colors ${
            activeTab === "profile"
              ? "border-primary text-primary"
              : "border-transparent text-on-surface-variant hover:text-on-surface"
          }`}
        >
          <User size={16} />
          Profile
        </button>
        <button
          onClick={() => setActiveTab("relays")}
          className={`flex items-center gap-2 px-4 py-3 text-sm font-semibold border-b-2 transition-colors ${
            activeTab === "relays"
              ? "border-primary text-primary"
              : "border-transparent text-on-surface-variant hover:text-on-surface"
          }`}
        >
          <Radio size={16} />
          Relays
        </button>
      </div>

      {/* Submissions tab */}
      {activeTab === "submissions" && (
        <>
          <section>
            <div className="flex items-center justify-between mb-8">
              <h2 className="text-xl font-bold text-on-surface">Submit a Post</h2>
              {!showForm && (
                <Button
                  variant="primary"
                  size="sm"
                  onClick={() => {
                    setShowForm(true);
                    setFormSuccess("");
                  }}
                >
                  <span className="flex items-center gap-2">
                    <Plus size={16} />
                    New Submission
                  </span>
                </Button>
              )}
            </div>

            {formSuccess && (
              <div className="bg-green-400/10 text-green-400 rounded-lg px-4 py-3 text-sm mb-6">
                {formSuccess}
              </div>
            )}

            {showForm && (
              <form
                onSubmit={handleSubmit}
                className="bg-surface-container-low rounded-xl p-6 mb-8 space-y-4"
              >
                <p className="text-on-surface-variant text-sm mb-2">
                  Submit a Nostr longform post for moderator review. Paste the
                  note ID or naddr of the article you&apos;d like published on the
                  blog. The title is pulled automatically from the note.
                </p>

                <div>
                  <label className="block text-xs font-bold uppercase tracking-widest text-on-surface-variant mb-2">
                    Note ID or naddr
                  </label>
                  <input
                    type="text"
                    value={noteInput}
                    onChange={(e) => setNoteInput(e.target.value)}
                    placeholder="naddr1... or note1... or hex event id"
                    className="w-full bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 font-mono text-sm placeholder:text-on-surface-variant/40 focus:outline-none focus:ring-1 focus:ring-primary/40"
                  />
                </div>

                {formError && (
                  <p className="text-error text-sm">{formError}</p>
                )}

                <div className="flex items-center gap-3 pt-2">
                  <Button
                    variant="primary"
                    size="md"
                    type="submit"
                    disabled={submitting}
                  >
                    <span className="flex items-center gap-2">
                      <Send size={16} />
                      {submitting ? "Fetching & submitting..." : "Submit for Review"}
                    </span>
                  </Button>
                  <Button
                    variant="secondary"
                    size="md"
                    type="button"
                    onClick={() => {
                      setShowForm(false);
                      setFormError("");
                    }}
                  >
                    Cancel
                  </Button>
                </div>
              </form>
            )}
          </section>

          <section>
            <h2 className="text-xl font-bold text-on-surface mb-6">My Submissions</h2>

            {loadingSubs ? (
              <div className="space-y-4">
                {[1, 2, 3].map((i) => (
                  <div key={i} className="animate-pulse bg-surface-container-low rounded-xl p-6">
                    <div className="h-5 w-2/3 bg-surface-container-high rounded mb-3" />
                    <div className="h-4 w-1/3 bg-surface-container-high rounded" />
                  </div>
                ))}
              </div>
            ) : submissions.length === 0 ? (
              <div className="bg-surface-container-low rounded-xl p-8 text-center">
                <FileText size={32} className="text-on-surface-variant/30 mx-auto mb-3" />
                <p className="text-on-surface-variant/60 text-sm">
                  No submissions yet. Submit a Nostr longform post for review.
                </p>
              </div>
            ) : (
              <div className="space-y-4">
                {submissions.map((sub) => {
                  const statusCfg = STATUS_CONFIG[sub.status] || STATUS_CONFIG.PENDING;
                  const StatusIcon = statusCfg.icon;
                  return (
                    <div
                      key={sub.id}
                      className="bg-surface-container-low rounded-xl p-6"
                    >
                      <div className="flex items-start justify-between gap-4">
                        <div className="flex-1 min-w-0">
                          <h3 className="font-semibold text-on-surface truncate">
                            {sub.title}
                          </h3>
                          <p className="text-on-surface-variant/60 text-xs mt-1">
                            {formatDate(sub.createdAt)}
                            {sub.eventId && (
                              <span className="ml-3 font-mono">
                                {sub.eventId.slice(0, 16)}...
                              </span>
                            )}
                            {sub.naddr && (
                              <span className="ml-3 font-mono">
                                {sub.naddr.slice(0, 20)}...
                              </span>
                            )}
                          </p>
                        </div>
                        <span
                          className={`flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-bold whitespace-nowrap ${statusCfg.className}`}
                        >
                          <StatusIcon size={14} />
                          {statusCfg.label}
                        </span>
                      </div>
                      {sub.reviewNote && (
                        <p className="mt-3 text-sm text-on-surface-variant bg-surface-container-high rounded-lg px-4 py-2">
                          {sub.reviewNote}
                        </p>
                      )}
                    </div>
                  );
                })}
              </div>
            )}
          </section>
        </>
      )}

      {/* Profile tab */}
      {activeTab === "profile" && (
        <section>
          <h2 className="text-xl font-bold text-on-surface mb-2">NIP-05 Username</h2>
          <p className="text-on-surface-variant text-sm mb-8">
            Claim a NIP-05 verified Nostr address hosted on this site. Other Nostr
            clients will display your identity as{" "}
            <span className="font-mono text-on-surface">username@{hostname || "…"}</span>.
          </p>

          <form
            onSubmit={handleSaveProfile}
            className="bg-surface-container-low rounded-xl p-6 space-y-5 max-w-lg"
          >
            <div>
              <label className="block text-xs font-bold uppercase tracking-widest text-on-surface-variant mb-2">
                Username
              </label>
              <div className="relative">
                <div className="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none">
                  <AtSign size={16} className="text-on-surface-variant/50" />
                </div>
                <input
                  type="text"
                  value={username}
                  onChange={(e) => handleUsernameChange(e.target.value)}
                  placeholder="yourname"
                  maxLength={50}
                  className="w-full bg-surface-container-highest text-on-surface rounded-lg pl-10 pr-10 py-3 font-mono text-sm placeholder:text-on-surface-variant/40 focus:outline-none focus:ring-1 focus:ring-primary/40"
                />
                <div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
                  {usernameStatus.state === "checking" && (
                    <Loader2 size={16} className="animate-spin text-on-surface-variant/50" />
                  )}
                  {usernameStatus.state === "available" && (
                    <CheckCircle size={16} className="text-green-400" />
                  )}
                  {usernameStatus.state === "unavailable" && (
                    <XCircle size={16} className="text-error" />
                  )}
                </div>
              </div>

              {/* Status message */}
              <div className="mt-2 min-h-[20px]">
                {usernameStatus.state === "checking" && (
                  <p className="text-xs text-on-surface-variant/60">Checking availability…</p>
                )}
                {usernameStatus.state === "available" && (
                  <p className="text-xs text-green-400">Available</p>
                )}
                {usernameStatus.state === "unavailable" && (
                  <p className="text-xs text-error">{usernameStatus.reason}</p>
                )}
              </div>
            </div>

            {/* NIP-05 preview */}
            {username.trim() && (
              <div className="bg-surface-container-highest rounded-lg px-4 py-3">
                <p className="text-xs text-on-surface-variant mb-1 uppercase tracking-widest font-bold">NIP-05 Address</p>
                <p className="font-mono text-sm text-on-surface break-all">
                  {username.trim().toLowerCase()}@{hostname || "…"}
                </p>
              </div>
            )}

            {saveError && (
              <p className="text-error text-sm">{saveError}</p>
            )}
            {saveSuccess && (
              <div className="bg-green-400/10 text-green-400 rounded-lg px-4 py-3 text-sm">
                {saveSuccess}
              </div>
            )}

            <Button
              variant="primary"
              size="md"
              type="submit"
              disabled={isSaveDisabled}
            >
              {saving ? "Saving…" : "Save Username"}
            </Button>
          </form>
        </section>
      )}

      {/* Relays tab */}
      {activeTab === "relays" && (
        <section>
          <h2 className="text-xl font-bold text-on-surface mb-2">Your Relays</h2>
          <p className="text-on-surface-variant text-sm mb-8">
            Manage the Nostr relays used for your interactions on this site.
            These relays are used when publishing events and fetching your content.
            You can also import your relay list from your Nostr profile (NIP-65).
          </p>

          {relaySuccess && (
            <div className="bg-green-400/10 text-green-400 rounded-lg px-4 py-3 text-sm mb-6">
              {relaySuccess}
            </div>
          )}
          {relayError && (
            <div className="bg-error/10 text-error rounded-lg px-4 py-3 text-sm mb-6">
              {relayError}
            </div>
          )}

          <div className="flex flex-col sm:flex-row gap-3 mb-8">
            <form onSubmit={handleAddRelay} className="flex-1 flex gap-3">
              <input
                type="text"
                value={newRelayUrl}
                onChange={(e) => setNewRelayUrl(e.target.value)}
                placeholder="wss://relay.example.com"
                className="flex-1 bg-surface-container-highest text-on-surface rounded-lg px-4 py-3 font-mono text-sm placeholder:text-on-surface-variant/40 focus:outline-none focus:ring-1 focus:ring-primary/40"
              />
              <Button
                variant="primary"
                size="md"
                type="submit"
                disabled={addingRelay}
              >
                <span className="flex items-center gap-2">
                  <Plus size={16} />
                  {addingRelay ? "Adding…" : "Add"}
                </span>
              </Button>
            </form>
            <Button
              variant="secondary"
              size="md"
              type="button"
              onClick={handleImportNip65}
              disabled={importingNip65}
            >
              <span className="flex items-center gap-2">
                {importingNip65 ? (
                  <Loader2 size={16} className="animate-spin" />
                ) : (
                  <Download size={16} />
                )}
                {importingNip65 ? "Importing…" : "Import from NIP-65"}
              </span>
            </Button>
          </div>

          {loadingRelays ? (
            <div className="space-y-3">
              {[1, 2, 3].map((i) => (
                <div key={i} className="animate-pulse bg-surface-container-low rounded-xl p-5">
                  <div className="h-5 w-2/3 bg-surface-container-high rounded" />
                </div>
              ))}
            </div>
          ) : userRelays.length === 0 ? (
            <div className="bg-surface-container-low rounded-xl p-8 text-center">
              <Radio size={32} className="text-on-surface-variant/30 mx-auto mb-3" />
              <p className="text-on-surface-variant/60 text-sm">
                No relays configured. Add a relay manually or import from your NIP-65 profile.
              </p>
            </div>
          ) : (
            <div className="space-y-3">
              {userRelays.map((relay) => (
                <div
                  key={relay.id}
                  className="bg-surface-container-low rounded-xl px-5 py-4 flex items-center justify-between gap-4"
                >
                  <div className="flex-1 min-w-0">
                    <p className="font-mono text-sm text-on-surface truncate">
                      {relay.url}
                    </p>
                    <div className="flex gap-2 mt-1.5">
                      {relay.read && (
                        <span className="flex items-center gap-1 text-xs font-semibold text-primary bg-primary/10 px-2 py-0.5 rounded-full">
                          <Eye size={12} />
                          Read
                        </span>
                      )}
                      {relay.write && (
                        <span className="flex items-center gap-1 text-xs font-semibold text-green-400 bg-green-400/10 px-2 py-0.5 rounded-full">
                          <Pencil size={12} />
                          Write
                        </span>
                      )}
                    </div>
                  </div>
                  <button
                    onClick={() => handleRemoveRelay(relay.id)}
                    className="text-on-surface-variant/50 hover:text-error transition-colors p-2 rounded-lg hover:bg-error/10"
                    title="Remove relay"
                  >
                    <Trash2 size={16} />
                  </button>
                </div>
              ))}
            </div>
          )}
        </section>
      )}
    </div>
  );
}
