'use client';

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { cn } from '@/utils/common';
import { Check, ChevronDown, ChevronUp, Search } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { Controller, useFormContext } from 'react-hook-form';

export interface Option {
    value: string | number;
    label: string;
    disabled?: boolean;
}

interface SelectFieldProps {
    name: string;
    options: Option[] | string[] | Record<string, any>;
    placeholder?: string;
    disabled?: boolean;
    className?: string;
    searchable?: boolean;
    searchPlaceholder?: string;
}

export const SelectField = ({ name, options, placeholder, disabled, className, searchable = false, searchPlaceholder = 'Search...' }: SelectFieldProps) => {
    const { control } = useFormContext();
    const [searchTerm, setSearchTerm] = useState('');
    const [isOpen, setIsOpen] = useState(false);
    const searchInputRef = useRef<HTMLInputElement>(null);

    // Helper function to normalize options to Option[] format
    const normalizeOptions = (opts: Option[] | string[] | Record<string, any> | undefined): Option[] => {
        if (!opts) return [];

        // Handle plain object / dictionary (e.g. { as: { name, flag, language } })
        if (!Array.isArray(opts)) {
            return Object.entries(opts).map(([key, value]) => {
                if (typeof value === 'string') {
                    return { value: key, label: value };
                }
                const label =
                    value?.flag && (value?.language || value?.name)
                        ? `${value.flag} ${value.language || value.name}`
                        : value?.language || value?.name || value?.label || value?.title || key;
                return { value: key, label };
            });
        }

        return opts.map((opt) => {
            if (typeof opt === 'string') {
                return { value: opt, label: opt };
            }
            return opt;
        });
    };

    const normalizedOptions = normalizeOptions(options);

    const filteredOptions = searchable
        ? normalizedOptions.filter((option) => option.label.toLowerCase().includes(searchTerm.toLowerCase()))
        : normalizedOptions;

    useEffect(() => {
        if (searchable && isOpen && searchInputRef.current) {
            setTimeout(() => searchInputRef.current?.focus(), 100);
        }
    }, [isOpen, searchable]);

    useEffect(() => {
        if (!isOpen) {
            setSearchTerm('');
        }
    }, [isOpen]);

    return (
        <Controller
            control={control}
            name={name}
            render={({ field }) => {
                const selectedOption = normalizedOptions.find((opt) => String(opt.value) === String(field.value));

                if (searchable) {
                    return (
                        <Popover open={isOpen} onOpenChange={setIsOpen}>
                            <PopoverTrigger asChild>
                                <Button
                                    variant="outline"
                                    role="combobox"
                                    aria-expanded={isOpen}
                                    className={cn(
                                        'h-10 w-full justify-between border-gray-300 text-left hover:bg-white',
                                        !field.value && 'text-muted-foreground',
                                        className,
                                    )}
                                    disabled={disabled}
                                >
                                    <span className={cn(!selectedOption && 'text-gray-500')}>
                                        {selectedOption ? selectedOption.label : placeholder || 'Select an option'}
                                    </span>
                                    {isOpen ? (
                                        <ChevronUp className="h-4 w-4 shrink-0 opacity-50" />
                                    ) : (
                                        <ChevronDown className="h-4 w-4 shrink-0 opacity-50" />
                                    )}
                                </Button>
                            </PopoverTrigger>
                            <PopoverContent className="w-full min-w-50 p-0" align="start">
                                <div className="flex items-center border-b px-3">
                                    <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
                                    <Input
                                        ref={searchInputRef}
                                        placeholder={searchPlaceholder}
                                        value={searchTerm}
                                        onChange={(e) => setSearchTerm(e.target.value)}
                                        className="border-0 focus-visible:ring-0"
                                    />
                                </div>
                                <div className="max-h-60 overflow-auto">
                                    {filteredOptions.length > 0 ? (
                                        filteredOptions.map((option) => {
                                            const isSelected = String(field.value) === String(option.value);
                                            return (
                                                <div
                                                    key={option.value}
                                                    className={cn(
                                                        'flex cursor-pointer items-center gap-2 px-3 py-2 text-sm hover:bg-muted',
                                                        option.disabled && 'cursor-not-allowed opacity-50',
                                                        isSelected && 'bg-brand-50',
                                                    )}
                                                    onClick={() => {
                                                        if (option.disabled) return;
                                                        field.onChange(option.value);
                                                        setIsOpen(false);
                                                        setSearchTerm('');
                                                    }}
                                                >
                                                    <span className={cn('flex-1', isSelected && 'font-medium text-success')}>
                                                        {option.label}
                                                    </span>
                                                    {isSelected && <Check className="h-4 w-4 shrink-0 text-success" />}
                                                </div>
                                            );
                                        })
                                    ) : (
                                        <div className="px-3 py-2 text-sm text-muted-foreground">
                                            No options found for &quot;{searchTerm}&quot;.
                                        </div>
                                    )}
                                </div>
                            </PopoverContent>
                        </Popover>
                    );
                }

                return (
                    <Select
                        value={field.value !== undefined && field.value !== null ? String(field.value) : undefined}
                        onValueChange={(value) => {
                            // Convert back to number if the original option value was a number
                            const originalOption = normalizedOptions.find((opt) => String(opt.value) === value);
                            field.onChange(originalOption ? originalOption.value : value);
                        }}
                        disabled={disabled}
                    >
                        <SelectTrigger className={cn(className)}>
                            <SelectValue placeholder={placeholder || 'Select an option'} />
                        </SelectTrigger>
                        <SelectContent>
                            {normalizedOptions.map((option) => (
                                <SelectItem key={option.value} value={String(option.value)} disabled={option.disabled}>
                                    {option.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                );
            }}
        />
    );
};
