import { router } from '@inertiajs/react';
import * as React from 'react';

import {
    Command,
    CommandEmpty,
    CommandInput,
    CommandItem,
    CommandList,
} from '@/components/ui/command';
import { Dialog, DialogBody, DialogContent } from '@/components/ui/dialog';
import { Icon } from '@/components/ui/icon';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { useGlobalSearch } from '@/hooks/use-global-search';
import { useI18n } from '@/hooks/use-i18n';
import { cn } from '@/lib/utils';
import type { SearchClientResult, SearchDocumentResult, SearchSupplierResult, SearchTab } from '@/types';

const ACCOUNTANT_STATUS_ICON: Record<string, string> = {
    validated: 'material-symbols:check-circle-outline',
    in_review: 'material-symbols:rate-review-outline',
    waiting:   'material-symbols:schedule-outline',
    rejected:  'material-symbols:cancel-outline',
};

const ACCOUNTANT_STATUS_CLASS: Record<string, string> = {
    validated: 'text-[var(--success)]',
    in_review: 'text-[var(--warning)]',
    waiting:   'text-muted-foreground',
    rejected:  'text-destructive',
};

const searchResultRowClass =
    'flex cursor-pointer gap-3 rounded-none border-b border-dashed border-border/50 py-2.5 last:border-b-0 hover:bg-primary/10 data-[selected=true]:bg-primary/10 data-[selected=true]:text-foreground';

function ClientRow({ result, onSelect }: { result: SearchClientResult; onSelect: () => void }) {
    return (
        <CommandItem
            value={`client-${result.client_id}-${result.name}`}
            onSelect={onSelect}
            className={cn(searchResultRowClass, 'items-center')}
        >
            <Icon icon="material-symbols:person-outline" className="size-4 shrink-0 text-muted-foreground" />
            <div className="min-w-0 flex-1">
                <div className="flex items-center justify-between gap-2">
                    <span className="truncate font-medium text-sm">{result.name}</span>
                    {!result.active && (
                        <span className="shrink-0 text-xs text-destructive">inactiv</span>
                    )}
                </div>
                {(result.cif || result.city) && (
                    <p className="text-xs text-muted-foreground truncate">
                        {[result.cif, result.city].filter(Boolean).join(' · ')}
                    </p>
                )}
            </div>
        </CommandItem>
    );
}

function SupplierRow({ result, onSelect }: { result: SearchSupplierResult; onSelect: () => void }) {
    return (
        <CommandItem
            value={`supplier-${result.supplier_id}-${result.name}`}
            onSelect={onSelect}
            className={cn(searchResultRowClass, 'items-center')}
        >
            <Icon icon="material-symbols:store-outline" className="size-4 shrink-0 text-muted-foreground" />
            <div className="min-w-0 flex-1">
                <div className="flex items-center justify-between gap-2">
                    <span className="truncate font-medium text-sm">{result.name}</span>
                    {!result.active && (
                        <span className="shrink-0 text-xs text-destructive">inactiv</span>
                    )}
                </div>
                {(result.cif || result.city) && (
                    <p className="text-xs text-muted-foreground truncate">
                        {[result.cif, result.city].filter(Boolean).join(' · ')}
                    </p>
                )}
            </div>
        </CommandItem>
    );
}

function DocumentRow({ result, onSelect }: { result: SearchDocumentResult; onSelect: () => void }) {
    const statusIcon = result.accountant_status
        ? (ACCOUNTANT_STATUS_ICON[result.accountant_status] ?? 'material-symbols:description-outline')
        : 'material-symbols:description-outline';
    const statusClass = result.accountant_status
        ? (ACCOUNTANT_STATUS_CLASS[result.accountant_status] ?? 'text-muted-foreground')
        : 'text-muted-foreground';

    return (
        <CommandItem
            value={`doc-${result.document_id}-${result.document_number ?? ''}-${result.issuer_name ?? ''}`}
            onSelect={onSelect}
            className={cn(searchResultRowClass, 'items-start')}
        >
            <Icon icon={statusIcon} className={cn('mt-0.5 size-4 shrink-0', statusClass)} />
            <div className="min-w-0 flex-1">
                <div className="flex items-baseline justify-between gap-2">
                    <span className="truncate font-medium text-sm">
                        {result.document_number ?? '—'}
                    </span>
                    {result.total_amount !== null && (
                        <span className="shrink-0 text-xs text-muted-foreground tabular-nums">
                            {Number(result.total_amount).toFixed(2)} {result.currency ?? ''}
                        </span>
                    )}
                </div>
                <p className="text-xs text-muted-foreground truncate">
                    {[result.issuer_name, result.issue_date, result.client_name]
                        .filter(Boolean)
                        .join(' · ')}
                </p>
            </div>
        </CommandItem>
    );
}

function TabBadge({ count }: { count: number }) {
    return (
        <span className="ml-1.5 inline-flex h-4 min-w-[1rem] items-center justify-center rounded-full bg-primary/15 px-1 text-[10px] font-medium text-primary">
            {count}
        </span>
    );
}

function EmptyTabContent({ label }: { label: string }) {
    return (
        <CommandEmpty className="py-8 text-center text-sm text-muted-foreground">
            {label}
        </CommandEmpty>
    );
}

interface GlobalSearchProps {
    open: boolean;
    onOpenChange: (open: boolean) => void;
}

export function GlobalSearch({ open, onOpenChange }: GlobalSearchProps) {
    const { t } = useI18n();
    const { query, clients, suppliers, documents, isLoading, setQuery, reset } = useGlobalSearch();
    const [activeTab, setActiveTab] = React.useState<SearchTab>('clients');

    const hasSearched = query.trim().length >= 2 && !isLoading;
    const availableTabs = React.useMemo<SearchTab[]>(() => {
        if (!hasSearched) return [];
        const tabs: SearchTab[] = [];
        if (clients.length > 0) tabs.push('clients');
        if (suppliers.length > 0) tabs.push('suppliers');
        if (documents.length > 0) tabs.push('documents');
        return tabs;
    }, [hasSearched, clients.length, suppliers.length, documents.length]);

    React.useEffect(() => {
        if (availableTabs.length > 0 && !availableTabs.includes(activeTab)) {
            setActiveTab(availableTabs[0]);
        }
    }, [availableTabs, activeTab]);

    const handleOpenChange = React.useCallback(
        (value: boolean) => {
            if (!value) {
                reset();
                setActiveTab('clients');
            }
            onOpenChange(value);
        },
        [onOpenChange, reset],
    );

    const handleSelectClient = React.useCallback(
        (result: SearchClientResult) => {
            handleOpenChange(false);
            router.visit(`/admin/clients/${result.client_id}`);
        },
        [handleOpenChange],
    );

    const handleSelectSupplier = React.useCallback(
        (result: SearchSupplierResult) => {
            handleOpenChange(false);
            router.visit(`/admin/suppliers?search=${encodeURIComponent(result.name)}`);
        },
        [handleOpenChange],
    );

    const handleSelectDocument = React.useCallback(
        (result: SearchDocumentResult) => {
            handleOpenChange(false);
            router.visit(`/admin/documents/${result.document_id}`);
        },
        [handleOpenChange],
    );

    const hasNoResults = hasSearched && availableTabs.length === 0;

    return (
        <Dialog open={open} onOpenChange={handleOpenChange}>
            <DialogContent className="overflow-hidden gap-0 p-0 sm:max-w-xl">
                <DialogBody className="p-0">
                <Command shouldFilter={false} loop>
                    <CommandInput
                        placeholder={t('common.search.placeholder')}
                        value={query}
                        onValueChange={setQuery}
                    />

                    {isLoading && (
                        <div className="py-8 text-center text-sm text-muted-foreground border-t">
                            {t('common.search.searching')}
                        </div>
                    )}

                    {!isLoading && query.trim().length < 2 && (
                        <div className="py-8 text-center text-sm text-muted-foreground border-t">
                            {t('common.search.hint')}
                        </div>
                    )}

                    {hasNoResults && (
                        <div className="py-8 text-center text-sm text-muted-foreground border-t">
                            {t('common.search.no_results')}
                        </div>
                    )}

                    {!isLoading && availableTabs.length > 0 && (
                        <Tabs
                            value={activeTab}
                            onValueChange={(v) => setActiveTab(v as SearchTab)}
                            className="border-t"
                        >
                            <TabsList variant="line" className="w-full px-3">
                                {availableTabs.includes('clients') && (
                                    <TabsTrigger variant="line" value="clients">
                                        {t('common.search.tab_clients')}
                                        <TabBadge count={clients.length} />
                                    </TabsTrigger>
                                )}
                                {availableTabs.includes('suppliers') && (
                                    <TabsTrigger variant="line" value="suppliers">
                                        {t('common.search.tab_suppliers')}
                                        <TabBadge count={suppliers.length} />
                                    </TabsTrigger>
                                )}
                                {availableTabs.includes('documents') && (
                                    <TabsTrigger variant="line" value="documents">
                                        {t('common.search.tab_documents')}
                                        <TabBadge count={documents.length} />
                                    </TabsTrigger>
                                )}
                            </TabsList>

                            <TabsContent value="clients">
                                <CommandList>
                                    {clients.length === 0
                                        ? <EmptyTabContent label={t('common.search.no_results')} />
                                        : clients.map((c) => (
                                            <ClientRow
                                                key={c.client_id}
                                                result={c}
                                                onSelect={() => handleSelectClient(c)}
                                            />
                                        ))
                                    }
                                </CommandList>
                            </TabsContent>

                            <TabsContent value="suppliers">
                                <CommandList>
                                    {suppliers.length === 0
                                        ? <EmptyTabContent label={t('common.search.no_results')} />
                                        : suppliers.map((s) => (
                                            <SupplierRow
                                                key={s.supplier_id}
                                                result={s}
                                                onSelect={() => handleSelectSupplier(s)}
                                            />
                                        ))
                                    }
                                </CommandList>
                            </TabsContent>

                            <TabsContent value="documents">
                                <CommandList>
                                    {documents.length === 0
                                        ? <EmptyTabContent label={t('common.search.no_results')} />
                                        : documents.map((d) => (
                                            <DocumentRow
                                                key={d.document_id}
                                                result={d}
                                                onSelect={() => handleSelectDocument(d)}
                                            />
                                        ))
                                    }
                                </CommandList>
                            </TabsContent>
                        </Tabs>
                    )}
                </Command>
                </DialogBody>
            </DialogContent>
        </Dialog>
    );
}
