import * as Y from "yjs";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "~/components/ui/dialog";
import { Input } from "~/components/ui/input";
import { Button } from "~/components/ui/button";
import { ColorPicker } from "../form/color_picker";
import { Label } from "~/components/ui/label";
import { IconPicker } from "../form/icon_picker";
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "~/components/ui/alert-dialog";
import { useCollection, useCollections } from "~/hooks/use-metadata";
import { type CollectionId, type CollectionProperty, deleteCollection } from "~/lib/metadata";
import Icon from "@mdi/react";
import { mdiPin, mdiPinOff, mdiPlus, mdiTrashCan } from "@mdi/js";
import { createCollectionProperty, deleteCollectionProperty } from "~/lib/property";
import { useEffect } from "react";
import { PropertyTypeCombobox } from "../form/property_type_combobox";

type CollectionSettingsDialogProps = {
    name?: string;
    collectionId: CollectionId;
    children: React.ReactNode;
};
export function CollectionSettingsDialog(props: CollectionSettingsDialogProps) {
    return (
        <Dialog>
            <DialogTrigger asChild>
                {props.children}
            </DialogTrigger>
            <DialogContent className="max-w-[800px]">
                <DialogHeader>
                    <DialogTitle>{props.name} settings</DialogTitle>
                    <DialogDescription>
                        Settings for the {props.name} collection.
                    </DialogDescription>
                </DialogHeader>
                <div className="h-[600px] overflow-scroll flex flex-col gap-4">
                    <SettingsSection collectionId={props.collectionId} />
                    <PropertiesSection collectionId={props.collectionId} />
                    <DangerSection collectionId={props.collectionId} />
                </div>
            </DialogContent>
        </Dialog>
    );
}

function SettingsSection(props: { collectionId: CollectionId }) {
    const collection = useCollection(props.collectionId)

    if (!collection) {
        return null;
    }

    return (
        <div className="flex flex-col gap-2 p-2">
            <div className="flex flex-row gap-2">
                <IconPicker
                    initialValue={collection.get("icon")}
                    onChange={(icon) => collection.set("icon", icon ?? "")}
                />
                <div className="grid flex-grow items-center gap-1.5">
                    <Label htmlFor="name">Name</Label>
                    <Input
                        id="name"
                        className="flex-grow"
                        defaultValue={collection.get("name")}
                        placeholder="Name..."
                        onChange={(name) => collection.set("name", name.currentTarget.value)}
                    />
                </div>
            </div>
            <ColorPicker
                initialValue={collection.get("color")}
                onChange={(color) => collection.set("color", color)}
            />
        </div>
    );
}

function PropertiesSection(props: { collectionId: CollectionId }) {
    const collection = useCollection(props.collectionId)

    if (!collection) {
        return null;
    }

    // Ensure that the properties array exists on the collection
    useEffect(() => {
        if (!collection.has("properties")) {
            collection.set("properties", new Y.Array() as any)
        }
    }, [collection])

    const properties = collection.get("properties");

    return (
        <div>
            <Header label="Properties">
                <Button
                    variant="ghost"
                    onClick={() => properties && createCollectionProperty(properties)}
                >
                    <Icon path={mdiPlus} size={.75} />
                </Button>
            </Header>
            <div className="flex flex-col gap-2 p-2">
                {properties?.map((property) =>
                    <PropertyItem key={property.get("id")}
                        property={property}
                        onDelete={() => deleteCollectionProperty(properties, property.get("id"))}
                    />
                )}
            </div>
        </div>
    );
}

type PropertyItemProps = {
    property: CollectionProperty,
    onDelete: () => void,
}
function PropertyItem(props: PropertyItemProps) {
    const { property: prop } = props;

    return (
        <div className="flex flex-row gap-2">
            <Input
                className="flex-grow"
                defaultValue={prop.get("name")}
                placeholder="Name..."
                onChange={(event) => prop.set("name", event.target.value)}
            />
            <PropertyTypeCombobox
                initialValue={prop.get("type")}
                onSelect={(type) => prop.set("type", type)}
            />

            <Button
                variant="outline"
                onClick={() => prop.set("pinned", !prop.get("pinned"))}
            >
                <Icon path={prop.get("pinned") ? mdiPinOff : mdiPin} size={.75} />
            </Button>

            <Button
                variant="destructive"
                onClick={props.onDelete}
            >
                <Icon path={mdiTrashCan} size={.75} />
            </Button>
        </div>
    );
}

function DangerSection(props: { collectionId: CollectionId }) {
    const collections = useCollections();

    return (
        <div>
            <Header label="Danger zone">
            </Header>
            <div className="flex flex-row gap-2 p-2 items-center">
                <div className="flex-grow flex flex-col gap-1">
                    <span className="text-sm font-bold">Delete collection</span>
                    <span className="text-xs text-zinc-400">Delete the collection and all items contained within. WARNING: This action is irreversible!</span>
                </div>
                <AlertDialog>
                    <AlertDialogTrigger asChild>
                        <Button
                            variant="destructive"
                        >
                            Delete
                        </Button>
                    </AlertDialogTrigger>
                    <AlertDialogContent>
                        <AlertDialogHeader>
                            <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
                            <AlertDialogDescription>
                                This action cannot be undone. This will permanently delete the collection and ALL items contained in it.
                            </AlertDialogDescription>
                        </AlertDialogHeader>
                        <AlertDialogFooter>
                            <AlertDialogCancel>Cancel</AlertDialogCancel>
                            <AlertDialogAction asChild>
                                <Button
                                    variant="destructive"
                                    // TODO: Navigate away from the page when clicked
                                    onClick={() => deleteCollection(collections, props.collectionId)}
                                >
                                    Delete
                                </Button>
                            </AlertDialogAction>
                        </AlertDialogFooter>
                    </AlertDialogContent>
                </AlertDialog>
            </div>
        </div>
    );
}

type HeaderProps = {
    label: string,
    children?: React.ReactNode,
}

function Header(props: HeaderProps) {
    return (
        <div className="flex flex-row gap-2 pr-2 items-center">
            <h1 className="font-bold flex-grow">{props.label}</h1>
            {props.children}
        </div>
    );
}
