import { Head, Link, router } from '@inertiajs/react';
import {
    ArrowTopRightOnSquareIcon,
    ChevronRightIcon,
    DocumentIcon,
    EyeIcon,
    FolderIcon,
    HomeIcon,
    MagnifyingGlassIcon,
    TrashIcon,
    LinkIcon,
} from '@heroicons/react/24/outline';
import { FormEvent, useState } from 'react';
import DocumentEntryController from '@/actions/App/Http/Controllers/Documents/DocumentEntryController';
import { CreateFolderDialog } from '@/components/documents/create-folder-dialog';
import { EditEntryDialog } from '@/components/documents/edit-entry-dialog';
import { UploadFileDialog } from '@/components/documents/upload-file-dialog';
import { CreateEmbedDialog } from '@/components/documents/create-embed-dialog';
import { DocumentEntryIcon } from '@/components/documents/document-entry-icon';
import { Pagination } from '@/components/pagination';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
    index,
    preview,
    show,
} from '@/routes/documents';
import type {
    DirectoryCapabilities,
    DocumentEntry,
    DocumentFolder,
    DocumentFolderBreadcrumb,
    DocumentIframe,
    DocumentMenuIconOption,
    PaginatedData,
} from '@/types';

type Props = {
    documentIframe: DocumentIframe;
    entries: PaginatedData<DocumentEntry>;
    currentFolder: DocumentFolder | null;
    folderBreadcrumbs: DocumentFolderBreadcrumb[];
    filters: {
        search: string;
    };
    capabilities: DirectoryCapabilities;
    iconOptions: DocumentMenuIconOption[];
};

function formatFileSize(bytes: number | null): string {
    if (!bytes) {
        return 'Tamaño no disponible';
    }

    const units = ['B', 'KB', 'MB', 'GB'];
    let size = bytes;
    let unitIndex = 0;

    while (size >= 1024 && unitIndex < units.length - 1) {
        size /= 1024;
        unitIndex++;
    }

    return `${size.toFixed(unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`;
}

export default function ShowDocumentIframe({
    documentIframe,
    entries,
    currentFolder,
    folderBreadcrumbs,
    filters,
    capabilities,
    iconOptions,
}: Props) {
    const [searchValue, setSearchValue] = useState(filters.search);

    const currentFolderId = currentFolder?.public_id ?? null;

    const submitSearch = (event: FormEvent<HTMLFormElement>) => {
        event.preventDefault();

        const search = searchValue.trim();

        router.get(
            show(documentIframe.public_id).url,
            {
                ...(currentFolderId
                    ? { folder: currentFolderId }
                    : {}),
                ...(search ? { search } : {}),
            },
            {
                preserveState: true,
                replace: true,
            },
        );
    };

    const clearSearch = () => {
        setSearchValue('');

        router.get(
            show(documentIframe.public_id).url,
            currentFolderId
                ? { folder: currentFolderId }
                : {},
            {
                preserveState: true,
                replace: true,
            },
        );
    };

    const deleteEntry = (entry: DocumentEntry) => {
        const target =
            entry.type === 'folder'
                ? 'esta carpeta y todo su contenido'
                : 'este archivo';

        if (
            !window.confirm(
                `¿Seguro que deseas eliminar ${target}? Esta acción no se puede deshacer.`,
            )
        ) {
            return;
        }

        router.delete(
            DocumentEntryController.destroy.url({
                documentIframe: documentIframe.public_id,
                documentEntry: entry.public_id,
            }),
            {
                preserveScroll: true,
            },
        );
    };

    const isDynamicRoot =
        documentIframe.view_type === 'dynamic'
        && currentFolder === null;

    return (
        <>
            <Head title={documentIframe.name} />

            <div className="flex flex-1 flex-col gap-6 p-4 md:p-6">
                <div className="flex flex-col gap-4 xl:flex-row xl:items-start xl:justify-between">
                    <div>
                        <h1 className="text-2xl font-semibold">
                            {documentIframe.name}
                        </h1>

                        <div className="mt-2 flex flex-wrap items-center gap-2">
                            <span className="rounded-full bg-secondary px-3 py-1 text-xs font-medium text-secondary-foreground">
                                {documentIframe.view_label}
                            </span>

                            <span className="text-sm text-muted-foreground">
                                {entries.total} elementos en esta ubicación
                            </span>
                        </div>
                    </div>

                    <div className="flex flex-wrap gap-2">
                        {capabilities.can_create_folder && (
                            <CreateFolderDialog
                                documentIframeId={
                                    documentIframe.public_id
                                }
                                parentId={currentFolderId}
                                dynamicRoot={isDynamicRoot}
                                iconOptions={iconOptions}
                            />
                        )}

                        {capabilities.can_upload_file && (
                            <UploadFileDialog
                                documentIframeId={
                                    documentIframe.public_id
                                }
                                parentId={currentFolderId}
                            />
                        )}

                        {capabilities.can_create_embed
                            && currentFolderId && (
                            <CreateEmbedDialog
                                documentIframeId={
                                    documentIframe.public_id
                                }
                                parentId={currentFolderId}
                            />
                        )}

                        <Button variant="outline" asChild>
                            <Link
                                href={preview(
                                    documentIframe.public_id,
                                )}
                            >
                                <EyeIcon className="size-5" />
                                Vista previa
                            </Link>
                        </Button>
                    </div>
                </div>

                <nav
                    aria-label="Navegación de carpetas"
                    className="flex flex-wrap items-center gap-1 rounded-xl border border-border bg-card px-4 py-3 text-sm"
                >
                    <Link
                        href={show(documentIframe.public_id)}
                        className="flex items-center gap-1.5 rounded-md px-2 py-1 font-medium transition hover:bg-accent"
                    >
                        <HomeIcon className="size-4" />
                        Inicio
                    </Link>

                    {folderBreadcrumbs.map((breadcrumb) => (
                        <div
                            key={breadcrumb.public_id}
                            className="flex items-center gap-1"
                        >
                            <ChevronRightIcon className="size-4 text-muted-foreground" />

                            <Link
                                href={show(
                                    documentIframe.public_id,
                                    {
                                        query: {
                                            folder: breadcrumb.public_id,
                                        },
                                    },
                                )}
                                className="rounded-md px-2 py-1 transition hover:bg-accent"
                            >
                                {breadcrumb.name}
                            </Link>
                        </div>
                    ))}
                </nav>

                <form
                    onSubmit={submitSearch}
                    className="flex flex-col gap-3 sm:flex-row"
                >
                    <div className="relative flex-1">
                        <MagnifyingGlassIcon className="absolute top-1/2 left-3 size-5 -translate-y-1/2 text-muted-foreground" />

                        <Input
                            value={searchValue}
                            onChange={(event) =>
                                setSearchValue(event.target.value)
                            }
                            placeholder="Buscar en esta ubicación..."
                            className="pl-10"
                        />
                    </div>

                    <Button type="submit">
                        Buscar
                    </Button>

                    {filters.search && (
                        <Button
                            type="button"
                            variant="outline"
                            onClick={clearSearch}
                        >
                            Limpiar
                        </Button>
                    )}
                </form>

                {documentIframe.view_type === 'dynamic'
                    && currentFolder === null && (
                    <div className="rounded-xl border border-primary/20 bg-primary/5 px-4 py-3 text-sm">
                        Las carpetas de este nivel representan las
                        opciones que aparecerán en el menú lateral del
                        iframe.
                    </div>
                )}

                {documentIframe.view_type === 'dynamic'
                    && currentFolder !== null && (
                    <div className="rounded-xl border border-primary/20 bg-primary/5 px-4 py-3 text-sm">
                        Estás administrando el contenido de la opción
                        <strong> {currentFolder.name}</strong>. En esta
                        vista no se permiten subcarpetas.
                    </div>
                )}

                {entries.data.length > 0 ? (
                    <div className="grid grid-cols-1 gap-5 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
                        {entries.data.map((entry) => (
                            <article
                                key={entry.public_id}
                                className="group flex min-h-60 flex-col rounded-2xl border border-border bg-card p-5 shadow-sm transition hover:shadow-md"
                            >
                                {entry.type === 'folder' ? (
                                    <Link
                                        href={show(
                                            documentIframe.public_id,
                                            {
                                                query: {
                                                    folder: entry.public_id,
                                                },
                                            },
                                        )}
                                        className="flex flex-1 flex-col items-center justify-center text-center"
                                    >
                                        <div className="flex size-20 items-center justify-center rounded-2xl bg-primary/10 transition group-hover:bg-primary/15">
                                            {isDynamicRoot ? (
                                                <DocumentEntryIcon
                                                    iconType={entry.icon_type}
                                                    iconName={entry.icon_name}
                                                    iconUrl={entry.icon_url}
                                                    className="size-11 text-primary"
                                                />
                                            ) : (
                                                <FolderIcon className="size-11 text-primary" />
                                            )}
                                        </div>

                                        <h2 className="mt-4 line-clamp-2 font-semibold">
                                            {entry.name}
                                        </h2>

                                        <p className="mt-2 text-xs text-muted-foreground">
                                            Orden: {entry.sort_order}
                                        </p>
                                    </Link>
                                ) : entry.type === 'file' ? (
                                    <a
                                        href={entry.file_url ?? '#'}
                                        target="_blank"
                                        rel="noreferrer"
                                        className="flex flex-1 flex-col items-center justify-center text-center"
                                    >
                                        <div className="flex size-20 items-center justify-center rounded-2xl bg-secondary">
                                            <DocumentIcon className="size-10 text-primary" />
                                        </div>

                                        <h2 className="mt-4 line-clamp-2 font-semibold">
                                            {entry.name}
                                        </h2>

                                        <div className="mt-2 space-y-1 text-xs text-muted-foreground">
                                            <p>
                                                Orden: {entry.sort_order}
                                            </p>

                                            <p>
                                                {formatFileSize(
                                                    entry.file_size,
                                                )}
                                            </p>
                                        </div>
                                    </a>
                                ) : (
                                    <div className="flex flex-1 flex-col items-center justify-center text-center">
                                        <div className="flex size-20 items-center justify-center rounded-2xl bg-primary/10">
                                            <LinkIcon className="size-10 text-primary" />
                                        </div>

                                        <h2 className="mt-4 line-clamp-2 font-semibold">
                                            {entry.name}
                                        </h2>

                                        <div className="mt-2 space-y-1 text-xs text-muted-foreground">
                                            <p>
                                                Orden: {entry.sort_order}
                                            </p>

                                            <p className="capitalize">
                                                Contenido embebido
                                            </p>
                                        </div>
                                    </div>
                                )}

                                <div className="mt-5 flex items-center justify-between border-t border-border pt-4">
                                    <span className="text-xs font-medium text-muted-foreground">
                                        {entry.type_label}
                                    </span>

                                    <div className="flex items-center gap-1">
                                        {entry.type === 'file'
                                            && entry.file_url && (
                                            <Button
                                                variant="ghost"
                                                size="icon"
                                                asChild
                                                title="Abrir archivo"
                                            >
                                                <a
                                                    href={
                                                        entry.file_url
                                                    }
                                                    target="_blank"
                                                    rel="noreferrer"
                                                >
                                                    <ArrowTopRightOnSquareIcon className="size-5" />
                                                </a>
                                            </Button>
                                        )}

                                        <EditEntryDialog
                                            documentIframeId={
                                                documentIframe.public_id
                                            }
                                            entry={entry}
                                        />

                                        <Button
                                            type="button"
                                            variant="ghost"
                                            size="icon"
                                            title="Eliminar"
                                            onClick={() =>
                                                deleteEntry(entry)
                                            }
                                        >
                                            <TrashIcon className="size-5 text-destructive" />
                                        </Button>
                                    </div>
                                </div>
                            </article>
                        ))}
                    </div>
                ) : (
                    <div className="flex min-h-72 flex-col items-center justify-center rounded-2xl border-2 border-dashed border-border bg-muted/20 p-8 text-center">
                        {currentFolder ? (
                            <FolderIcon className="size-16 text-muted-foreground/50" />
                        ) : (
                            <DocumentIcon className="size-16 text-muted-foreground/50" />
                        )}

                        <h2 className="mt-5 text-lg font-semibold">
                            {filters.search
                                ? 'No se encontraron resultados'
                                : 'Esta ubicación está vacía'}
                        </h2>

                        <p className="mt-2 max-w-md text-sm text-muted-foreground">
                            {filters.search
                                ? `No hay contenido que coincida con "${filters.search}".`
                                : capabilities.can_create_folder
                                  ? 'Crea una carpeta para comenzar a organizar el contenido.'
                                  : 'Sube un archivo para comenzar a agregar contenido.'}
                        </p>
                    </div>
                )}

                <Pagination {...entries} />
            </div>
        </>
    );
}

ShowDocumentIframe.layout = {
    breadcrumbs: [
        {
            title: 'Documentos',
            href: index(),
        },
    ],
};