import * as React from 'react';
import { useState } from 'react';
import { SearchableSelect } from '@/components/ui/searchable-select';
import { api } from '@/lib/api';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label';

export interface CheckoutField {
    key: string;
    fieldset: 'billing' | 'shipping' | 'account' | 'order';
    type: string;
    label: string;
    placeholder?: string;
    required: boolean;
    hidden: boolean;
    class?: string[];
    priority: number;
    options?: Record<string, string> | null;
    custom: boolean;
    autocomplete?: string;
    validate?: string[];
    input_class?: string[];
    custom_attributes?: Record<string, string>;
    default?: string;
    // For searchable_select type
    search_endpoint?: string | null;
    search_param?: string;
    min_chars?: number;
}

interface DynamicCheckoutFieldProps {
    field: CheckoutField;
    value: string;
    onChange: (value: string) => void;
    countryOptions?: { value: string; label: string }[];
    stateOptions?: { value: string; label: string }[];
}

interface SearchOption {
    value: string;
    label: string;
}

export function DynamicCheckoutField({
    field,
    value,
    onChange,
    countryOptions = [],
    stateOptions = [],
}: DynamicCheckoutFieldProps) {
    const [searchOptions, setSearchOptions] = useState<SearchOption[]>([]);
    const [isSearching, setIsSearching] = useState(false);

    // Handle API search for searchable_select
    const handleApiSearch = async (searchTerm: string) => {
        if (!field.search_endpoint) return;

        const minChars = field.min_chars || 2;
        if (searchTerm.length < minChars) {
            setSearchOptions([]);
            return;
        }

        setIsSearching(true);
        try {
            const param = field.search_param || 'search';
            const results = await api.get<SearchOption[]>(field.search_endpoint, { [param]: searchTerm });
            setSearchOptions(Array.isArray(results) ? results : []);
        } catch (error) {
            console.error('Search failed:', error);
            setSearchOptions([]);
        } finally {
            setIsSearching(false);
        }
    };

    // Don't render hidden fields
    if (field.hidden || field.type === 'hidden') {
        return null;
    }

    // Get field key without prefix (billing_, shipping_)
    const fieldName = field.key.replace(/^(billing_|shipping_)/, '');

    // Determine CSS classes
    const isWide = ['address_1', 'address_2', 'email'].includes(fieldName) ||
        field.class?.includes('form-row-wide');
    const wrapperClass = isWide ? 'md:col-span-2' : '';

    // Render based on type
    const renderInput = () => {
        switch (field.type) {
            case 'country':
                return (
                    <SearchableSelect
                        options={countryOptions}
                        value={value}
                        onChange={onChange}
                        placeholder={field.placeholder || 'Select country'}
                        disabled={countryOptions.length <= 1}
                    />
                );

            case 'state':
                return stateOptions.length > 0 ? (
                    <SearchableSelect
                        options={stateOptions}
                        value={value}
                        onChange={onChange}
                        placeholder={field.placeholder || 'Select state'}
                    />
                ) : (
                    <Input
                        type="text"
                        value={value}
                        onChange={(e) => onChange(e.target.value)}
                        placeholder={field.placeholder}
                        required={field.required}
                        autoComplete={field.autocomplete}
                    />
                );

            case 'select':
                if (field.options && Object.keys(field.options).length > 0) {
                    const options = Object.entries(field.options).map(([val, label]) => ({
                        value: val,
                        label: String(label),
                    }));
                    return (
                        <SearchableSelect
                            options={options}
                            value={value}
                            onChange={onChange}
                            placeholder={field.placeholder || `Select ${field.label}`}
                        />
                    );
                }
                return null;

            case 'searchable_select':
                return (
                    <SearchableSelect
                        options={searchOptions}
                        value={value}
                        onChange={(v) => {
                            onChange(v);
                            // Store label for display
                            const selected = searchOptions.find(o => o.value === v);
                            if (selected) {
                                const event = new CustomEvent('woonoow:field_label', {
                                    detail: { key: field.key + '_label', value: selected.label }
                                });
                                document.dispatchEvent(event);
                            }
                        }}
                        onSearch={handleApiSearch}
                        isSearching={isSearching}
                        placeholder={field.placeholder || `Search ${field.label}...`}
                        emptyLabel={
                            isSearching
                                ? 'Searching...'
                                : `Type at least ${field.min_chars || 2} characters to search`
                        }
                    />
                );

            case 'textarea':
                return (
                    <Textarea
                        value={value}
                        onChange={(e) => onChange(e.target.value)}
                        placeholder={field.placeholder}
                        required={field.required}
                    />
                );

            case 'checkbox':
                return (
                    <label className="flex items-center gap-2">
                        <input
                            type="checkbox"
                            checked={value === '1' || value === 'true'}
                            onChange={(e) => onChange(e.target.checked ? '1' : '0')}
                            className="w-4 h-4"
                        />
                        <span>{field.label}</span>
                    </label>
                );

            case 'radio':
                if (field.options) {
                    return (
                        <div className="space-y-2">
                            {Object.entries(field.options).map(([val, label]) => (
                                <label key={val} className="flex items-center gap-2">
                                    <input
                                        type="radio"
                                        name={field.key}
                                        value={val}
                                        checked={value === val}
                                        onChange={() => onChange(val)}
                                        className="w-4 h-4"
                                    />
                                    <span>{String(label)}</span>
                                </label>
                            ))}
                        </div>
                    );
                }
                return null;

            case 'email':
                return (
                    <Input
                        type="email"
                        value={value}
                        onChange={(e) => onChange(e.target.value)}
                        placeholder={field.placeholder}
                        required={field.required}
                        autoComplete={field.autocomplete || 'email'}
                    />
                );

            case 'tel':
                return (
                    <Input
                        type="tel"
                        value={value}
                        onChange={(e) => onChange(e.target.value)}
                        placeholder={field.placeholder}
                        required={field.required}
                        autoComplete={field.autocomplete || 'tel'}
                    />
                );

            // Default: text input
            default:
                return (
                    <Input
                        type="text"
                        value={value}
                        onChange={(e) => onChange(e.target.value)}
                        placeholder={field.placeholder}
                        required={field.required}
                        autoComplete={field.autocomplete}
                    />
                );
        }
    };

    // Don't render label for checkbox (it's inline)
    if (field.type === 'checkbox') {
        return (
            <div className={wrapperClass}>
                {renderInput()}
            </div>
        );
    }

    return (
        <div className={wrapperClass}>
            <Label>
                {field.label}
                {field.required && <span className="text-destructive ml-1">*</span>}
            </Label>
            {renderInput()}
        </div>
    );
}
