"use client";

import { useState } from "react";
import { useEffect } from "react";
import {
  createFooterLink,
  createFooterPage,
  deleteFooterLink,
  deleteFooterPage,
  updateFooterLink,
  updateFooterPage,
  type PageContent,
} from "@/lib/actions/footer";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  AlertDialog,
  AlertDialogClose,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { ExternalLink, Pencil, Plus, Trash2 } from "lucide-react";

type PageRow = {
  id: string;
  title: string;
  slug: string;
  description: string | null;
  content: PageContent;
  isPublished: boolean;
};

type LinkRow = {
  id: string;
  sectionId: string;
  label: string;
  href: string;
  platform: string | null;
  pageId: string | null;
  isEnabled: boolean;
  sortOrder: number;
  page: { id: string; title: string; slug: string } | null;
};

type SectionRow = {
  id: string;
  title: string;
  type: "LINKS" | "SOCIAL";
  links: LinkRow[];
};

type Props = {
  initialData: { pages: PageRow[]; sections: SectionRow[] };
};

type Notice = { kind: "success" | "error"; text: string } | null;

function Notice({ notice }: { notice: Notice }) {
  if (!notice) return null;
  return (
    <div
      role={notice.kind === "error" ? "alert" : "status"}
      className="rounded-md border px-3 py-2 text-sm"
    >
      {notice.text}
    </div>
  );
}
function ToastNotice({ notice }: { notice: Notice }) {
  const [dismissedNotice, setDismissedNotice] = useState<Notice>(null);

  useEffect(() => {
    if (!notice) return;
    const timeout = window.setTimeout(() => setDismissedNotice(notice), 2800);
    return () => window.clearTimeout(timeout);
  }, [notice]);

  if (!notice || dismissedNotice === notice) return null;
  return (
    <div
      role={notice.kind === "error" ? "alert" : "status"}
      className="fixed right-4 bottom-4 z-50 max-w-sm rounded-md border bg-background px-4 py-3 text-sm shadow-lg"
    >
      {notice.text}
    </div>
  );
}

function PageEditor({
  page,
  open,
  onOpenChange,
  onSaved,
}: {
  page?: PageRow;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSaved: (page: PageRow, editing: boolean) => void;
}) {
  const editing = Boolean(page);
  const [title, setTitle] = useState(page?.title ?? "");
  const [slug, setSlug] = useState(page?.slug ?? "");
  const [description, setDescription] = useState(page?.description ?? "");
  const [content, setContent] = useState<PageContent>(
    page?.content ?? { sections: [{ heading: "", body: "" }] },
  );
  const [isPublished, setIsPublished] = useState(page?.isPublished ?? false);
  const [notice, setNotice] = useState<Notice>(null);
  const [saving, setSaving] = useState(false);

  function updateSection(
    index: number,
    key: "heading" | "body",
    value: string,
  ) {
    setContent((current) => ({
      sections: current.sections.map((section, sectionIndex) =>
        sectionIndex === index ? { ...section, [key]: value } : section,
      ),
    }));
  }

  async function submit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    setNotice(null);
    const result = editing
      ? await updateFooterPage(page!.id, {
          title,
          slug,
          description,
          content,
          isPublished,
        })
      : await createFooterPage({
          title,
          slug,
          description,
          content,
          isPublished,
        });
    setSaving(false);
    if (!result.ok) {
      setNotice({ kind: "error", text: result.error });
      return;
    }
    onSaved(result.data as PageRow, editing);
    onOpenChange(false);
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-2xl">
        <DialogHeader>
          <DialogTitle>
            {editing ? "Edit footer page" : "Create footer page"}
          </DialogTitle>
          <DialogDescription>
            Draft content is private until you publish it.
          </DialogDescription>
        </DialogHeader>
        <form className="flex flex-col gap-4" onSubmit={submit}>
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="flex flex-col gap-2">
              <Label htmlFor="page-title">Title</Label>
              <Input
                id="page-title"
                value={title}
                onChange={(event) => setTitle(event.target.value)}
                required
              />
            </div>
            <div className="flex flex-col gap-2">
              <Label htmlFor="page-slug">Slug</Label>
              <Input
                id="page-slug"
                value={slug}
                onChange={(event) => setSlug(event.target.value)}
                placeholder="shipping"
                required
              />
            </div>
          </div>
          <div className="flex flex-col gap-2">
            <Label htmlFor="page-description">Description</Label>
            <Textarea
              id="page-description"
              value={description}
              onChange={(event) => setDescription(event.target.value)}
              rows={2}
            />
          </div>
          <div className="flex flex-col gap-3">
            <div className="flex items-center justify-between">
              <Label>Content sections</Label>
              <Button
                type="button"
                variant="outline"
                size="sm"
                onClick={() =>
                  setContent((current) => ({
                    sections: [...current.sections, { heading: "", body: "" }],
                  }))
                }
              >
                <Plus data-icon="inline-start" />
                Add section
              </Button>
            </div>
            {content.sections.map((section, index) => (
              <div className="rounded-md border p-3" key={index}>
                <div className="flex items-center justify-between gap-3">
                  <span className="text-xs font-medium text-muted-foreground">
                    Section {index + 1}
                  </span>
                  {content.sections.length > 1 && (
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      onClick={() =>
                        setContent((current) => ({
                          sections: current.sections.filter(
                            (_, sectionIndex) => sectionIndex !== index,
                          ),
                        }))
                      }
                    >
                      <Trash2 data-icon="inline-start" />
                      Remove
                    </Button>
                  )}
                </div>
                <div className="mt-3 flex flex-col gap-3">
                  <Input
                    aria-label={`Section ${index + 1} heading`}
                    placeholder="Heading"
                    value={section.heading}
                    onChange={(event) =>
                      updateSection(index, "heading", event.target.value)
                    }
                    required
                  />
                  <Textarea
                    aria-label={`Section ${index + 1} body`}
                    placeholder="Body"
                    value={section.body}
                    onChange={(event) =>
                      updateSection(index, "body", event.target.value)
                    }
                    rows={4}
                    required
                  />
                </div>
              </div>
            ))}
          </div>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={isPublished}
              onChange={(event) => setIsPublished(event.target.checked)}
            />{" "}
            Published
          </label>
          <Notice notice={notice} />
          <ToastNotice notice={notice} />
          <DialogFooter>
            <Button
              type="button"
              variant="outline"
              onClick={() => onOpenChange(false)}
              disabled={saving}
            >
              Cancel
            </Button>
            <Button type="submit" disabled={saving}>
              {saving ? "Saving..." : editing ? "Save changes" : "Create page"}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function LinkEditor({
  link,
  sections,
  pages,
  open,
  onOpenChange,
  onSaved,
}: {
  link?: LinkRow;
  sections: SectionRow[];
  pages: PageRow[];
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSaved: (link: LinkRow, editing: boolean) => void;
}) {
  const editing = Boolean(link);
  const [sectionId, setSectionId] = useState(
    link?.sectionId ?? sections[0]?.id ?? "",
  );
  const [label, setLabel] = useState(link?.label ?? "");
  const [href, setHref] = useState(link?.href ?? "");
  const [pageId, setPageId] = useState(link?.pageId ?? "");
  const [platform, setPlatform] = useState(link?.platform ?? "");
  const [sortOrder, setSortOrder] = useState(String(link?.sortOrder ?? 0));
  const [isEnabled, setIsEnabled] = useState(link?.isEnabled ?? true);
  const [notice, setNotice] = useState<Notice>(null);
  const [saving, setSaving] = useState(false);

  async function submit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    setNotice(null);
    const result = editing
      ? await updateFooterLink(link!.id, {
          sectionId,
          label,
          href: pageId ? "" : href,
          pageId: pageId || undefined,
          platform: platform || undefined,
          isEnabled,
          sortOrder: Number(sortOrder) || 0,
        })
      : await createFooterLink({
          sectionId,
          label,
          href: pageId ? "" : href,
          pageId: pageId || undefined,
          platform: platform || undefined,
          isEnabled,
          sortOrder: Number(sortOrder) || 0,
        });
    setSaving(false);
    if (!result.ok) {
      setNotice({ kind: "error", text: result.error });
      return;
    }
    onSaved(result.data as LinkRow, editing);
    onOpenChange(false);
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>
            {editing ? "Edit footer link" : "Add footer link"}
          </DialogTitle>
          <DialogDescription>
            Choose a page for automatic slug updates, or enter a URL.
          </DialogDescription>
        </DialogHeader>
        <form className="flex flex-col gap-4" onSubmit={submit}>
          <div className="flex flex-col gap-2">
            <Label htmlFor="link-section">Section</Label>
            <select
              id="link-section"
              className="h-9 rounded-md border bg-background px-3 text-sm"
              value={sectionId}
              onChange={(event) => setSectionId(event.target.value)}
            >
              {sections.map((section) => (
                <option key={section.id} value={section.id}>
                  {section.title}
                </option>
              ))}
            </select>
          </div>
          <div className="flex flex-col gap-2">
            <Label htmlFor="link-label">Display label</Label>
            <Input
              id="link-label"
              value={label}
              onChange={(event) => setLabel(event.target.value)}
              required
            />
          </div>
          <div className="flex flex-col gap-2">
            <Label htmlFor="link-page">Internal page (optional)</Label>
            <select
              id="link-page"
              className="h-9 rounded-md border bg-background px-3 text-sm"
              value={pageId}
              onChange={(event) => setPageId(event.target.value)}
            >
              <option value="">Use a URL instead</option>
              {pages.map((page) => (
                <option key={page.id} value={page.id}>
                  {page.title} (/pages/{page.slug})
                </option>
              ))}
            </select>
          </div>
          {!pageId && (
            <div className="flex flex-col gap-2">
              <Label htmlFor="link-url">URL</Label>
              <Input
                id="link-url"
                value={href}
                onChange={(event) => setHref(event.target.value)}
                placeholder="/products or https://..."
                required
              />
            </div>
          )}
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="flex flex-col gap-2">
              <Label htmlFor="link-platform">Platform (social only)</Label>
              <Input
                id="link-platform"
                value={platform}
                onChange={(event) => setPlatform(event.target.value)}
                placeholder="Instagram"
              />
            </div>
            <div className="flex flex-col gap-2">
              <Label htmlFor="link-order">Display order</Label>
              <Input
                id="link-order"
                type="number"
                min="0"
                value={sortOrder}
                onChange={(event) => setSortOrder(event.target.value)}
              />
            </div>
          </div>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={isEnabled}
              onChange={(event) => setIsEnabled(event.target.checked)}
            />{" "}
            Enabled
          </label>
          <Notice notice={notice} />
          <DialogFooter>
            <Button
              type="button"
              variant="outline"
              onClick={() => onOpenChange(false)}
              disabled={saving}
            >
              Cancel
            </Button>
            <Button type="submit" disabled={saving}>
              {saving ? "Saving..." : editing ? "Save changes" : "Add link"}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export default function FooterManagementClient({ initialData }: Props) {
  const [pages, setPages] = useState(initialData.pages);
  const [sections, setSections] = useState(initialData.sections);
  const [tab, setTab] = useState<"pages" | "links">("pages");
  const [pageEditor, setPageEditor] = useState<{
    open: boolean;
    page?: PageRow;
  }>({ open: false });
  const [linkEditor, setLinkEditor] = useState<{
    open: boolean;
    link?: LinkRow;
  }>({ open: false });
  const [confirm, setConfirm] = useState<{
    type: "page" | "link";
    id: string;
  } | null>(null);
  const [notice, setNotice] = useState<Notice>(null);

  function handlePageSaved(page: PageRow, editing: boolean) {
    setPages((current) =>
      editing
        ? current.map((item) => (item.id === page.id ? page : item))
        : [...current, page].sort((a, b) => a.title.localeCompare(b.title)),
    );
    setNotice({
      kind: "success",
      text: editing ? "Page updated." : "Page created.",
    });
  }

  function handleLinkSaved(link: LinkRow, editing: boolean) {
    setSections((current) =>
      current.map((section) => ({
        ...section,
        links: editing
          ? section.links
              .filter((item) => item.id !== link.id)
              .concat(section.id === link.sectionId ? [link] : [])
              .sort((a, b) => a.sortOrder - b.sortOrder)
          : section.id === link.sectionId
            ? [...section.links, link].sort((a, b) => a.sortOrder - b.sortOrder)
            : section.links,
      })),
    );
    setNotice({
      kind: "success",
      text: editing ? "Footer link updated." : "Footer link added.",
    });
  }

  async function removeConfirmed() {
    if (!confirm) return;
    const result =
      confirm.type === "page"
        ? await deleteFooterPage(confirm.id)
        : await deleteFooterLink(confirm.id);
    setConfirm(null);
    if (!result.ok) {
      setNotice({ kind: "error", text: result.error });
      return;
    }
    if (confirm.type === "page")
      setPages((current) => current.filter((page) => page.id !== confirm.id));
    else
      setSections((current) =>
        current.map((section) => ({
          ...section,
          links: section.links.filter((link) => link.id !== confirm.id),
        })),
      );
    setNotice({ kind: "success", text: result.message ?? "Deleted." });
  }

  const links = sections.flatMap((section) =>
    section.links.map((link) => ({ ...link, sectionTitle: section.title })),
  );

  return (
    <div className="flex flex-col gap-6">
      <ToastNotice notice={notice} />
      <div className="flex flex-wrap items-end justify-between gap-3">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">Footer & Pages</h1>
          <p className="text-sm text-muted-foreground">
            Manage published content, footer destinations, and social profiles.
          </p>
        </div>
        <Button
          onClick={() =>
            tab === "pages"
              ? setPageEditor({ open: true })
              : setLinkEditor({ open: true })
          }
        >
          <Plus data-icon="inline-start" />
          {tab === "pages" ? "New page" : "New link"}
        </Button>
      </div>
      <Notice notice={notice} />
      <div className="flex gap-1 border-b">
        <Button
          variant={tab === "pages" ? "secondary" : "ghost"}
          onClick={() => setTab("pages")}
        >
          Pages ({pages.length})
        </Button>
        <Button
          variant={tab === "links" ? "secondary" : "ghost"}
          onClick={() => setTab("links")}
        >
          Footer links ({links.length})
        </Button>
      </div>
      {tab === "pages" ? (
        <div className="grid gap-3">
          {pages.length === 0 ? (
            <Card>
              <CardContent className="py-10 text-center text-sm text-muted-foreground">
                No pages yet. Create the first footer page.
              </CardContent>
            </Card>
          ) : (
            pages.map((page) => (
              <Card key={page.id}>
                <CardHeader className="flex-row items-start justify-between gap-4">
                  <div>
                    <CardTitle className="text-base">{page.title}</CardTitle>
                    <CardDescription>/pages/{page.slug}</CardDescription>
                  </div>
                  <Badge variant={page.isPublished ? "default" : "secondary"}>
                    {page.isPublished ? "Published" : "Draft"}
                  </Badge>
                </CardHeader>
                <CardContent className="flex flex-wrap items-center justify-between gap-3">
                  <p className="line-clamp-2 max-w-2xl text-sm text-muted-foreground">
                    {page.description || "No description"}
                  </p>
                  <div className="flex gap-2">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() =>
                        window.open(
                          `/pages/${page.slug}?preview=1`,
                          "_blank",
                          "noopener,noreferrer",
                        )
                      }
                    >
                      <ExternalLink data-icon="inline-start" />
                      Preview
                    </Button>
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setPageEditor({ open: true, page })}
                    >
                      <Pencil data-icon="inline-start" />
                      Edit
                    </Button>
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => setConfirm({ type: "page", id: page.id })}
                    >
                      <Trash2 data-icon="inline-start" />
                      Delete
                    </Button>
                  </div>
                </CardContent>
              </Card>
            ))
          )}
        </div>
      ) : (
        <div className="grid gap-4">
          {sections.map((section) => (
            <Card key={section.id}>
              <CardHeader>
                <div className="flex items-center justify-between gap-3">
                  <div>
                    <CardTitle className="text-base">{section.title}</CardTitle>
                    <CardDescription>
                      {section.type === "SOCIAL"
                        ? "External social profiles"
                        : "Storefront navigation"}
                    </CardDescription>
                  </div>
                  <Badge variant="outline">{section.links.length} links</Badge>
                </div>
              </CardHeader>
              <CardContent className="flex flex-col gap-2">
                {section.links.map((link) => (
                  <div
                    key={link.id}
                    className="flex flex-wrap items-center justify-between gap-3 rounded-md border px-3 py-2"
                  >
                    <div className="min-w-0">
                      <div className="flex items-center gap-2">
                        <span className="font-medium">{link.label}</span>
                        <Badge
                          variant={link.isEnabled ? "secondary" : "outline"}
                        >
                          {link.isEnabled ? "Enabled" : "Disabled"}
                        </Badge>
                      </div>
                      <p className="truncate text-xs text-muted-foreground">
                        {link.page
                          ? `/pages/${link.page.slug}`
                          : link.href || "No URL configured"}{" "}
                        · order {link.sortOrder}
                      </p>
                    </div>
                    <div className="flex gap-1">
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => setLinkEditor({ open: true, link })}
                      >
                        <Pencil data-icon="inline-start" />
                        Edit
                      </Button>
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() =>
                          setConfirm({ type: "link", id: link.id })
                        }
                      >
                        <Trash2 data-icon="inline-start" />
                        Delete
                      </Button>
                    </div>
                  </div>
                ))}
              </CardContent>
            </Card>
          ))}
        </div>
      )}
      <PageEditor
        key={pageEditor.page?.id ?? "new-page"}
        page={pageEditor.page}
        open={pageEditor.open}
        onOpenChange={(open) =>
          setPageEditor((current) => ({ ...current, open }))
        }
        onSaved={handlePageSaved}
      />
      <LinkEditor
        key={linkEditor.link?.id ?? "new-link"}
        link={linkEditor.link}
        sections={sections}
        pages={pages}
        open={linkEditor.open}
        onOpenChange={(open) =>
          setLinkEditor((current) => ({ ...current, open }))
        }
        onSaved={handleLinkSaved}
      />
      <AlertDialog
        open={Boolean(confirm)}
        onOpenChange={(open) => !open && setConfirm(null)}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete this {confirm?.type}?</AlertDialogTitle>
            <AlertDialogDescription>
              This cannot be undone. Existing page links will stop displaying if
              the page is deleted.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogClose render={<Button variant="outline" />}>
              Cancel
            </AlertDialogClose>
            <Button variant="destructive" onClick={removeConfirmed}>
              Delete
            </Button>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
