"use client";

import * as React from "react";
import Image from "next/image";
import {
  User,
  Globe,
  Link2,
  AtSign,
  Share2,
  Camera,
  Link as LinkIcon,
  ImagePlus,
  ExternalLink,
  Check,
  Loader2,
  Upload,
} from "lucide-react";
import { FloatingInput, FloatingTextarea } from "@/components/ui/floating-field";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { toast } from "sonner";

interface Socials {
  linkedin: string;
  instagram: string;
  x: string;
  website: string;
  github: string;
  youtube: string;
}

interface ProfileForm {
  id: string;
  name: string;
  email: string;
  level: string;
  role: string;
  displayName: string;
  jobTitle: string;
  shortBio: string;
  longBio: string;
  location: string;
  professionalEmail: string;
  authorSlug: string;
  avatarUrl: string | null;
  avatarMediaId: string | null;
  socials: Socials;
}

interface MediaItem {
  id: string;
  url: string;
  alt: string;
  originalName: string;
}

const EMPTY_SOCIALS: Socials = {
  linkedin: "",
  instagram: "",
  x: "",
  website: "",
  github: "",
  youtube: "",
};

const SOCIAL_FIELDS: {
  key: keyof Socials;
  label: string;
  icon: React.ComponentType<{ className?: string }>;
  placeholder: string;
}[] = [
  { key: "linkedin", label: "LinkedIn URL", icon: Link2, placeholder: "https://linkedin.com/in/…" },
  { key: "instagram", label: "Instagram URL", icon: Camera, placeholder: "https://instagram.com/…" },
  { key: "x", label: "X (Twitter) URL", icon: AtSign, placeholder: "https://x.com/…" },
  { key: "website", label: "Personal Website", icon: Globe, placeholder: "https://…" },
  { key: "github", label: "GitHub URL", icon: LinkIcon, placeholder: "https://github.com/…" },
  { key: "youtube", label: "YouTube URL", icon: Share2, placeholder: "https://youtube.com/@…" },
];

export function ProfilePanel() {
  const [form, setForm] = React.useState<ProfileForm | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  const load = React.useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch("/api/admin/profile");
      if (!res.ok) throw new Error("Failed to load profile");
      const data = await res.json();
      const p = data.profile;
      setForm({ ...p, socials: { ...EMPTY_SOCIALS, ...(p.socials || {}) } });
    } catch (e) {
      setError((e as Error).message);
    } finally {
      setLoading(false);
    }
  }, []);

  React.useEffect(() => {
    load();
  }, [load]);

  const set = <K extends keyof ProfileForm>(key: K, value: ProfileForm[K]) =>
    setForm((f) => (f ? { ...f, [key]: value } : f));
  const setSocial = (key: keyof Socials, value: string) =>
    setForm((f) => (f ? { ...f, socials: { ...f.socials, [key]: value } } : f));

  const handleSave = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!form) return;
    setSaving(true);
    setError(null);
    try {
      const res = await fetch("/api/admin/profile", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          displayName: form.displayName,
          jobTitle: form.jobTitle,
          shortBio: form.shortBio,
          longBio: form.longBio,
          location: form.location,
          professionalEmail: form.professionalEmail,
          authorSlug: form.authorSlug,
          avatarUrl: form.avatarUrl,
          avatarMediaId: form.avatarMediaId,
          socials: form.socials,
        }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Failed to save profile");
      setForm({ ...data.profile, socials: { ...EMPTY_SOCIALS, ...(data.profile.socials || {}) } });
      toast.success("Profile saved. Your public author page will reflect the changes.");
    } catch (err) {
      setError((err as Error).message);
      toast.error((err as Error).message);
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return <div className="py-12 text-center text-xs text-neutral-400">Loading profile…</div>;
  }
  if (!form) {
    return (
      <div className="rounded-xl border border-red-200 bg-red-50 p-4 text-xs text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-300">
        {error || "Failed to load profile."}
      </div>
    );
  }

  const isMain = form.level === "MAIN_ADMIN";
  const completeness = [
    { label: "Display name", done: !!form.displayName },
    { label: "Profile image", done: !!form.avatarUrl },
    { label: "Job title", done: !!form.jobTitle },
    { label: "Short bio", done: !!form.shortBio },
    { label: "A social link", done: Object.values(form.socials).some(Boolean) },
  ];
  const completeCount = completeness.filter((c) => c.done).length;

  return (
    <form onSubmit={handleSave} className="space-y-6">
      {error && (
        <div role="alert" className="rounded-lg border border-red-200 bg-red-50 p-3 text-xs text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-300">
          {error}
        </div>
      )}

      {/* Profile header card */}
      <div className="rounded-2xl border border-neutral-200 bg-white p-6 shadow-xs dark:border-neutral-800 dark:bg-neutral-900">
        <div className="flex flex-col gap-5 sm:flex-row sm:items-center">
          <AvatarPicker
            url={form.avatarUrl}
            name={form.displayName || form.name}
            onChange={(url, id) => setForm((f) => (f ? { ...f, avatarUrl: url, avatarMediaId: id } : f))}
          />
          <div className="min-w-0 flex-1">
            <h2 className="truncate text-lg font-bold text-neutral-900 dark:text-white">
              {form.displayName || form.name}
            </h2>
            <p className="truncate text-xs text-neutral-500">
              {form.jobTitle || (isMain ? "Main Administrator" : (form.role || "ADMIN").replace(/_/g, " "))}
            </p>
            <p className="mt-0.5 truncate text-[11px] text-neutral-400">{form.email}</p>
            <div className="mt-2 flex flex-wrap items-center gap-2">
              <span className={`rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider ${isMain ? "bg-neutral-900 text-white dark:bg-white dark:text-neutral-900" : "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300"}`}>
                {isMain ? "Main Admin" : (form.role || "ADMIN").replace(/_/g, " ")}
              </span>
              {form.authorSlug && (
                <a
                  href={`/author/${form.authorSlug}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="inline-flex items-center gap-1 text-[11px] font-medium text-neutral-500 hover:text-neutral-900 dark:hover:text-white"
                >
                  <ExternalLink className="h-3 w-3" /> Preview public author
                </a>
              )}
            </div>
          </div>
          {/* Completeness */}
          <div className="shrink-0 rounded-xl border border-neutral-200 bg-neutral-50 p-3 dark:border-neutral-800 dark:bg-neutral-950">
            <div className="text-[10px] font-bold uppercase tracking-wider text-neutral-400">
              Author profile · {completeCount}/{completeness.length}
            </div>
            <ul className="mt-1.5 space-y-1">
              {completeness.map((c) => (
                <li key={c.label} className={`flex items-center gap-1.5 text-[11px] ${c.done ? "text-emerald-600 dark:text-emerald-400" : "text-neutral-400"}`}>
                  <Check className={`h-3 w-3 ${c.done ? "opacity-100" : "opacity-30"}`} /> {c.label}
                </li>
              ))}
            </ul>
          </div>
        </div>
      </div>

      {/* Identity */}
      <Section title="Identity">
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
          <FloatingInput id="p-displayName" label="Display Name" autoComplete="name" value={form.displayName} onChange={(e) => set("displayName", e.target.value)} />
          <FloatingInput id="p-jobTitle" label="Job Title (e.g. Senior AI Content Strategist)" value={form.jobTitle} onChange={(e) => set("jobTitle", e.target.value)} />
          <FloatingInput id="p-location" label="Location (optional)" autoComplete="address-level2" value={form.location} onChange={(e) => set("location", e.target.value)} />
          <FloatingInput id="p-profEmail" label="Professional Email (optional)" type="email" autoComplete="email" value={form.professionalEmail} onChange={(e) => set("professionalEmail", e.target.value)} />
          <FloatingInput id="p-slug" label="Author Slug" value={form.authorSlug} onChange={(e) => set("authorSlug", e.target.value)} helper={`Public page: /author/${form.authorSlug || "your-slug"}`} />
        </div>
      </Section>

      {/* Author bio */}
      <Section title="Author Bio">
        <div className="space-y-4">
          <FloatingTextarea id="p-shortBio" label="Short Bio (author card, ~1–2 sentences)" rows={2} value={form.shortBio} onChange={(e) => set("shortBio", e.target.value)} maxLength={280} />
          <FloatingTextarea id="p-longBio" label="Long Description (author page)" rows={5} value={form.longBio} onChange={(e) => set("longBio", e.target.value)} />
        </div>
      </Section>

      {/* Social & professional */}
      <Section title="Social & Professional">
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
          {SOCIAL_FIELDS.map(({ key, label, icon: Icon, placeholder }) => (
            <div key={key} className="relative">
              <Icon className="pointer-events-none absolute right-3.5 top-1/2 z-[2] h-4 w-4 -translate-y-1/2 text-neutral-300 dark:text-neutral-600" />
              <FloatingInput
                id={`p-social-${key}`}
                label={label}
                type="url"
                inputMode="url"
                placeholder={placeholder}
                value={form.socials[key]}
                onChange={(e) => setSocial(key, e.target.value)}
                className="pr-10"
              />
            </div>
          ))}
        </div>
        <p className="mt-2 text-[11px] text-neutral-400">Only https links are accepted; each URL is validated on the server.</p>
      </Section>

      <div className="flex items-center justify-end gap-3">
        <Button type="submit" disabled={saving} className="rounded-xl text-xs font-semibold">
          {saving ? (
            <span className="inline-flex items-center gap-2"><Loader2 className="h-3.5 w-3.5 animate-spin" /> Saving…</span>
          ) : (
            "Save Profile"
          )}
        </Button>
      </div>
    </form>
  );
}

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <div className="rounded-2xl border border-neutral-200 bg-white p-6 shadow-xs dark:border-neutral-800 dark:bg-neutral-900">
      <h3 className="mb-4 text-sm font-bold text-neutral-900 dark:text-white">{title}</h3>
      {children}
    </div>
  );
}

/** Avatar shown as image or initials, with a Media Library picker dialog. */
function AvatarPicker({
  url,
  name,
  onChange,
}: {
  url: string | null;
  name: string;
  onChange: (url: string | null, id: string | null) => void;
}) {
  const [open, setOpen] = React.useState(false);
  const initials = name.trim().split(/\s+/).map((p) => p[0]).slice(0, 2).join("").toUpperCase() || "?";

  return (
    <div className="flex flex-col items-center gap-2">
      <div className="relative h-20 w-20 overflow-hidden rounded-2xl border border-neutral-200 bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-800">
        {url ? (
          <Image src={url} alt={`${name} avatar`} fill sizes="80px" className="object-cover" />
        ) : (
          <div className="flex h-full w-full items-center justify-center text-lg font-bold text-neutral-400">
            {initials}
          </div>
        )}
      </div>
      <div className="flex items-center gap-2">
        <Button type="button" variant="outline" size="sm" className="h-7 gap-1.5 text-[11px]" onClick={() => setOpen(true)}>
          <ImagePlus className="h-3 w-3" /> {url ? "Change" : "Add"}
        </Button>
        {url && (
          <button type="button" onClick={() => onChange(null, null)} className="text-[11px] text-neutral-400 hover:text-red-600">
            Remove
          </button>
        )}
      </div>
      <MediaPickerDialog open={open} onOpenChange={setOpen} onPick={(m) => { onChange(m.url, m.id); setOpen(false); }} />
    </div>
  );
}

function MediaPickerDialog({
  open,
  onOpenChange,
  onPick,
}: {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  onPick: (m: MediaItem) => void;
}) {
  const [items, setItems] = React.useState<MediaItem[]>([]);
  const [loading, setLoading] = React.useState(false);
  const [uploading, setUploading] = React.useState(false);
  const fileRef = React.useRef<HTMLInputElement>(null);

  const load = React.useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch("/api/admin/media");
      const data = await res.json();
      setItems(data.items || []);
    } catch {
      /* ignore */
    } finally {
      setLoading(false);
    }
  }, []);

  React.useEffect(() => {
    if (open) load();
  }, [open, load]);

  const handleUpload = async (file: File) => {
    setUploading(true);
    try {
      const fd = new FormData();
      fd.append("file", file);
      fd.append("alt", file.name.replace(/\.[^.]+$/, ""));
      fd.append("category", "author");
      const res = await fetch("/api/admin/media", { method: "POST", body: fd });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "Upload failed");
      onPick(data.media as MediaItem);
    } catch (e) {
      toast.error((e as Error).message);
    } finally {
      setUploading(false);
      if (fileRef.current) fileRef.current.value = "";
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>Choose profile image</DialogTitle>
          <DialogDescription>Pick from the shared Media Library, or upload a new image.</DialogDescription>
        </DialogHeader>

        <div className="mb-3 flex items-center justify-between">
          <span className="text-xs text-neutral-500">{items.length} item{items.length === 1 ? "" : "s"}</span>
          <input ref={fileRef} type="file" accept="image/*" hidden onChange={(e) => { const f = e.target.files?.[0]; if (f) handleUpload(f); }} />
          <Button type="button" variant="outline" size="sm" className="gap-1.5 text-xs" disabled={uploading} onClick={() => fileRef.current?.click()}>
            {uploading ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Upload className="h-3.5 w-3.5" />} Upload new
          </Button>
        </div>

        {loading ? (
          <div className="py-10 text-center text-xs text-neutral-400">Loading media…</div>
        ) : items.length === 0 ? (
          <div className="py-10 text-center text-xs text-neutral-400">No media yet. Upload an image to get started.</div>
        ) : (
          <div className="grid max-h-[50vh] grid-cols-3 gap-2 overflow-y-auto sm:grid-cols-4">
            {items.map((m) => (
              <button
                key={m.id}
                type="button"
                onClick={() => onPick(m)}
                className="group relative aspect-square overflow-hidden rounded-lg border border-neutral-200 hover:border-neutral-900 dark:border-neutral-700 dark:hover:border-white"
                title={m.originalName}
              >
                <Image src={m.url} alt={m.alt || m.originalName} fill sizes="120px" className="object-cover" />
              </button>
            ))}
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}

export default ProfilePanel;
