"use client";

import { useMemo, useRef, useState, useTransition } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import type { PromotionalMaterial } from "@/lib/types";
import { addMaterial, deleteMaterial } from "./actions";

export type MaterialWithUrl = PromotionalMaterial & {
  signedUrl: string | null;
};

const UNCATEGORIZED = "Uncategorized";

/* -------------------------------------------------------------------------- */
/* Add material dialog                                                        */
/* -------------------------------------------------------------------------- */

function AddMaterialDialog({ categories }: { categories: string[] }) {
  const [open, setOpen] = useState(false);
  const [categoryMode, setCategoryMode] = useState<string>("__new__");
  const [pending, startTransition] = useTransition();
  const formRef = useRef<HTMLFormElement>(null);

  function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);

    // When an existing category is chosen, the Select drives the value.
    if (categoryMode !== "__new__") {
      formData.set("category", categoryMode);
    }

    const title = (formData.get("title") as string | null)?.trim();
    if (!title) {
      toast.error("Title is required");
      return;
    }
    const file = formData.get("file");
    const hasFile = file instanceof File && file.size > 0;
    const link = (formData.get("link_url") as string | null)?.trim();
    if (!hasFile && !link) {
      toast.error("Provide either a file or an external link");
      return;
    }

    startTransition(async () => {
      const res = await addMaterial(formData);
      if (res.error) {
        toast.error(res.error);
      } else {
        toast.success("Material added");
        formRef.current?.reset();
        setCategoryMode("__new__");
        setOpen(false);
      }
    });
  }

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button>Add material</Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>Add promotional material</DialogTitle>
          <DialogDescription>
            Upload a file or share an external link. A title is required.
          </DialogDescription>
        </DialogHeader>
        <form ref={formRef} onSubmit={onSubmit} className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="pm-title">Title</Label>
            <Input id="pm-title" name="title" required />
          </div>

          <div className="space-y-2">
            <Label htmlFor="pm-category">Category</Label>
            {categories.length > 0 ? (
              <Select value={categoryMode} onValueChange={setCategoryMode}>
                <SelectTrigger id="pm-category">
                  <SelectValue placeholder="Choose a category" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="__new__">New category…</SelectItem>
                  {categories.map((c) => (
                    <SelectItem key={c} value={c}>
                      {c}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            ) : null}
            {categoryMode === "__new__" ? (
              <Input
                name="category"
                placeholder="e.g. Brochures, Banners, Social"
              />
            ) : null}
          </div>

          <div className="space-y-2">
            <Label htmlFor="pm-description">Description (optional)</Label>
            <textarea
              id="pm-description"
              name="description"
              rows={3}
              className="flex w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none placeholder:text-muted-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50"
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="pm-link">External link (optional)</Label>
            <Input
              id="pm-link"
              name="link_url"
              type="url"
              placeholder="https://…"
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="pm-file">File (optional)</Label>
            <Input id="pm-file" name="file" type="file" />
            <p className="text-xs text-muted-foreground">
              Provide a file or a link (or both). Max 25MB.
            </p>
          </div>

          <DialogFooter>
            <Button type="submit" disabled={pending}>
              {pending ? "Saving…" : "Add material"}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

/* -------------------------------------------------------------------------- */
/* Material card                                                              */
/* -------------------------------------------------------------------------- */

function MaterialCard({
  material,
  canManage,
}: {
  material: MaterialWithUrl;
  canManage: boolean;
}) {
  const [pending, startTransition] = useTransition();

  function remove() {
    if (!confirm(`Delete "${material.title}"?`)) return;
    startTransition(async () => {
      const res = await deleteMaterial(material.id, material.file_path);
      if (res.error) toast.error(res.error);
      else toast.success("Material deleted");
    });
  }

  return (
    <Card className="flex flex-col">
      <CardHeader>
        <CardTitle className="text-base">{material.title}</CardTitle>
        {material.description ? (
          <CardDescription>{material.description}</CardDescription>
        ) : null}
      </CardHeader>
      <CardContent className="flex-1">
        <div className="flex flex-wrap gap-2">
          {material.file_path ? <Badge variant="secondary">File</Badge> : null}
          {material.link_url ? <Badge variant="outline">Link</Badge> : null}
        </div>
      </CardContent>
      <CardFooter className="flex flex-wrap items-center justify-between gap-2">
        <div className="flex flex-wrap gap-3">
          {material.file_path && material.signedUrl ? (
            <a
              href={material.signedUrl}
              target="_blank"
              rel="noopener noreferrer"
              className="text-sm text-brand-blue underline underline-offset-4"
            >
              Download
            </a>
          ) : null}
          {material.file_path && !material.signedUrl ? (
            <span className="text-sm text-muted-foreground">
              File unavailable
            </span>
          ) : null}
          {material.link_url ? (
            <a
              href={material.link_url}
              target="_blank"
              rel="noopener noreferrer"
              className="text-sm text-brand-blue underline underline-offset-4"
            >
              Open link
            </a>
          ) : null}
        </div>
        {canManage ? (
          <Button
            size="sm"
            variant="destructive"
            disabled={pending}
            onClick={remove}
          >
            Delete
          </Button>
        ) : null}
      </CardFooter>
    </Card>
  );
}

/* -------------------------------------------------------------------------- */
/* Main client component                                                      */
/* -------------------------------------------------------------------------- */

export function MaterialsClient({
  materials,
  categories,
  canManage,
}: {
  materials: MaterialWithUrl[];
  categories: string[];
  canManage: boolean;
}) {
  const grouped = useMemo(() => {
    const map = new Map<string, MaterialWithUrl[]>();
    for (const m of materials) {
      const key = m.category?.trim() || UNCATEGORIZED;
      const list = map.get(key) ?? [];
      list.push(m);
      map.set(key, list);
    }
    return Array.from(map.entries()).sort(([a], [b]) =>
      a.localeCompare(b),
    );
  }, [materials]);

  return (
    <div className="space-y-8">
      {canManage ? (
        <div className="flex justify-end">
          <AddMaterialDialog categories={categories} />
        </div>
      ) : null}

      {materials.length === 0 ? (
        <p className="text-sm text-muted-foreground">
          No promotional materials yet.
        </p>
      ) : (
        grouped.map(([category, items]) => (
          <section key={category} className="space-y-4">
            <h2 className="text-lg font-semibold tracking-tight text-brand-navy">
              {category}
            </h2>
            <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
              {items.map((m) => (
                <MaterialCard
                  key={m.id}
                  material={m}
                  canManage={canManage}
                />
              ))}
            </div>
          </section>
        ))
      )}
    </div>
  );
}
