import { useCallback, useState } from "react";
import { Hash, Loader2, Plus, Newspaper } from "lucide-react";
import { api } from "@/client";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import type { Category } from "./channel-sidebar";

type Props = {
  workspaceId: string;
  categories: Category[];
  children: React.ReactNode;
  open?: boolean;
  onOpenChange?: (open: boolean) => void;
  onCreated?: () => void;
};

export default function RoomCreateDialog({
  workspaceId,
  categories,
  children,
  open: controlledOpen,
  onOpenChange: controlledOnOpenChange,
  onCreated,
}: Props) {
  const [internalOpen, setInternalOpen] = useState(false);
  const open = controlledOpen ?? internalOpen;
  const setOpen = controlledOnOpenChange ?? setInternalOpen;
  const [name, setName] = useState("");
  const [isPublic, setIsPublic] = useState(true);
  const [channelType, setChannelType] = useState("channel");
  const [categoryId, setCategoryId] = useState("");
  const [newCategoryName, setNewCategoryName] = useState("");
  const [creatingCategory, setCreatingCategory] = useState(false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState("");

  const handleCreateCategory = useCallback(async () => {
    const trimmed = newCategoryName.trim();
    if (!trimmed) return;
    setCreatingCategory(true);
    try {
      await api.post(`/api/v1/ws/workspaces/${workspaceId}/categories`, {
        name: trimmed,
      });
      setNewCategoryName("");
      onCreated?.();
    } catch {
      setError("Failed to create category");
    } finally {
      setCreatingCategory(false);
    }
  }, [newCategoryName, workspaceId, onCreated]);

  const handleCreate = useCallback(async () => {
    const trimmed = name.trim();
    if (!trimmed) {
      setError("Channel name is required");
      return;
    }
    setSaving(true);
    setError("");
    try {
      await api.post("/api/v1/ws/rooms", {
        workspace: workspaceId,
        room_name: trimmed,
        public: isPublic,
        category: categoryId || null,
        channel_type: channelType === "channel" ? null : channelType,
      });
      setName("");
      setIsPublic(true);
      setChannelType("channel");
      setCategoryId("");
      setNewCategoryName("");
      setOpen(false);
      onCreated?.();
    } catch {
      setError("Failed to create channel");
    } finally {
      setSaving(false);
    }
  }, [name, isPublic, channelType, categoryId, workspaceId, onCreated, setOpen]);

  return (
    <Dialog onOpenChange={setOpen} open={open}>
      <DialogTrigger>{children}</DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2 text-base">
            {channelType === "article" ? (
              <Newspaper className="size-5 text-primary/60" />
            ) : (
              <Hash className="size-5 text-primary/60" />
            )}
            Create Channel
          </DialogTitle>
          <DialogDescription>
            Create a new channel in this workspace.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* Channel type selector */}
          <div className="space-y-2">
            <Label className="text-[13px]">Channel type</Label>
            <div className="flex gap-2">
              <button
                className={`flex flex-1 cursor-pointer items-center gap-2 rounded-lg border px-3 py-2.5 text-sm transition-[background-color,border-color,color,box-shadow] ${
                  channelType === "channel"
                    ? "border-primary/40 bg-primary/[0.06] text-foreground"
                    : "border-border/30 text-muted-foreground/60 hover:border-border/50"
                }`}
                onClick={() => setChannelType("channel")}
                type="button"
              >
                <Hash className="size-4" />
                Chat
              </button>
              <button
                className={`flex flex-1 cursor-pointer items-center gap-2 rounded-lg border px-3 py-2.5 text-sm transition-[background-color,border-color,color,box-shadow] ${
                  channelType === "article"
                    ? "border-primary/40 bg-primary/[0.06] text-foreground"
                    : "border-border/30 text-muted-foreground/60 hover:border-border/50"
                }`}
                onClick={() => setChannelType("article")}
                type="button"
              >
                <Newspaper className="size-4" />
                Article
              </button>
            </div>
          </div>

          <div className="space-y-2">
            <Label className="text-[13px]" htmlFor="channel-name">
              Channel name
            </Label>
            <Input
              autoFocus
              id="channel-name"
              maxLength={100}
              onChange={(e) => {
                setName(e.target.value);
                setError("");
              }}
              placeholder="e.g. general, random"
              value={name}
            />
          </div>

          <div className="space-y-2">
            <Label className="text-[13px]">Category</Label>
            {categories.length > 0 ? (
              <select
                className="flex h-9 w-full cursor-pointer rounded-md border border-border/40 bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus:border-primary/30 focus:outline-none"
                onChange={(e) => setCategoryId(e.target.value)}
                value={categoryId}
              >
                <option value="">No category</option>
                {categories.map((cat) => (
                  <option key={cat.id} value={cat.id}>
                    {cat.name}
                  </option>
                ))}
              </select>
            ) : (
              <p className="text-xs text-muted-foreground/40">
                No categories yet — create one below
              </p>
            )}

            <div className="flex gap-2">
              <Input
                className="h-8 flex-1 text-sm"
                onChange={(e) => setNewCategoryName(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") {
                    e.preventDefault();
                    handleCreateCategory();
                  }
                }}
                placeholder="New category name…"
                value={newCategoryName}
              />
              <Button
                className="h-8 shrink-0 cursor-pointer"
                disabled={!newCategoryName.trim() || creatingCategory}
                onClick={handleCreateCategory}
                size="sm"
                variant="outline"
              >
                {creatingCategory ? (
                  <Loader2 className="size-3.5 animate-spin" />
                ) : (
                  <Plus className="size-3.5" />
                )}
              </Button>
            </div>
          </div>

          <div className="flex items-center justify-between rounded-lg border border-border/30 px-3 py-2.5">
            <div className="space-y-0.5">
              <Label
                className="text-[13px] font-medium"
                htmlFor="channel-public"
              >
                Public channel
              </Label>
              <p className="text-[11px] text-muted-foreground/40">
                Anyone in the workspace can join
              </p>
            </div>
            <Switch
              checked={isPublic}
              id="channel-public"
              onCheckedChange={setIsPublic}
            />
          </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>

        <DialogFooter>
          <Button
            className="cursor-pointer"
            onClick={() => setOpen(false)}
            variant="outline"
          >
            Cancel
          </Button>
          <Button
            className="cursor-pointer"
            disabled={saving || !name.trim()}
            onClick={handleCreate}
          >
            {saving && <Loader2 className="mr-2 size-4 animate-spin" />}
            Create Channel
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
