"use client";

import React from "react";
import { cn } from "@/lib/utils";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Slider } from "@/components/ui/slider";
import { Checkbox } from "@/components/ui/checkbox";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
import { FieldConfig } from "@/types/admin-panel";

interface FieldRendererProps {
    field: FieldConfig;
    value: any;
    error?: string;
    disabled?: boolean;
    onChange: (value: any) => void;
    onBlur?: () => void;
    className?: string;
}

export function FieldRenderer({
    field,
    value,
    error,
    disabled = false,
    onChange,
    onBlur,
    className
}: FieldRendererProps) {
    const isDisabled = disabled || field.disabled;
    const isReadOnly = field.readOnly;

    // Use custom render function if provided
    if (field.render) {
        return (
            <div className={className}>
                {field.render(field, value, onChange)}
            </div>
        );
    }

    const commonProps = {
        id: field.id,
        disabled: isDisabled,
        readOnly: isReadOnly,
        placeholder: field.placeholder,
        onBlur,
        className: cn(
            error && "border-destructive focus-visible:ring-destructive",
            className
        ),
    };

    const renderField = () => {
        switch (field.type) {
            case "input":
            case "email":
            case "url":
            case "tel":
                return (
                    <Input
                        {...commonProps}
                        type={field.type === "input" ? "text" : field.type}
                        value={value || ""}
                        onChange={(e) => onChange(e.target.value)}
                    />
                );

            case "password":
                return (
                    <Input
                        {...commonProps}
                        type="password"
                        value={value || ""}
                        onChange={(e) => onChange(e.target.value)}
                    />
                );

            case "number":
                return (
                    <Input
                        {...commonProps}
                        type="number"
                        min={field.min}
                        max={field.max}
                        step={field.step}
                        value={value || ""}
                        onChange={(e) => onChange(e.target.value ? Number(e.target.value) : "")}
                    />
                );

            case "textarea":
                return (
                    <Textarea
                        {...commonProps}
                        rows={field.rows || 3}
                        value={value || ""}
                        onChange={(e) => onChange(e.target.value)}
                    />
                );

            case "select":
                return (
                    <Select
                        value={value?.toString() || ""}
                        onValueChange={(newValue) => {
                            // Convert back to number if the original value was a number
                            const option = field.options?.find(opt => opt.value?.toString() === newValue);
                            onChange(option ? option.value : newValue);
                        }}
                        disabled={isDisabled}
                    >
                        <SelectTrigger className={cn(
                            error && "border-destructive focus:ring-destructive",
                            className
                        )}>
                            <SelectValue placeholder={field.placeholder || "请选择..."} />
                        </SelectTrigger>
                        <SelectContent>
                            {field.options?.map((option) => (
                                <SelectItem
                                    key={option.value}
                                    value={option.value.toString()}
                                    disabled={option.disabled}
                                >
                                    <div>
                                        <div>{option.label}</div>
                                        {option.description && (
                                            <div className="text-xs text-muted-foreground">
                                                {option.description}
                                            </div>
                                        )}
                                    </div>
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                );

            case "switch":
                return (
                    <Switch
                        id={field.id}
                        checked={Boolean(value)}
                        onCheckedChange={onChange}
                        disabled={isDisabled}
                        className={cn(
                            error && "border-destructive",
                            className
                        )}
                    />
                );

            case "checkbox":
                return (
                    <Checkbox
                        id={field.id}
                        checked={Boolean(value)}
                        onCheckedChange={onChange}
                        disabled={isDisabled}
                        className={cn(
                            error && "border-destructive",
                            className
                        )}
                    />
                );

            case "radio":
                return (
                    <RadioGroup
                        value={value?.toString() || ""}
                        onValueChange={(newValue) => {
                            const option = field.options?.find(opt => opt.value?.toString() === newValue);
                            onChange(option ? option.value : newValue);
                        }}
                        disabled={isDisabled}
                        className={className}
                    >
                        {field.options?.map((option) => (
                            <div key={option.value} className="flex items-center space-x-2">
                                <RadioGroupItem
                                    value={option.value.toString()}
                                    id={`${field.id}-${option.value}`}
                                    disabled={option.disabled}
                                />
                                <Label
                                    htmlFor={`${field.id}-${option.value}`}
                                    className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
                                >
                                    {option.label}
                                </Label>
                                {option.description && (
                                    <span className="text-xs text-muted-foreground ml-2">
                                        {option.description}
                                    </span>
                                )}
                            </div>
                        ))}
                    </RadioGroup>
                );

            case "slider":
            case "range":
                const sliderValue = Array.isArray(value) ? value : [value || field.min || 0];
                return (
                    <div className="space-y-3">
                        <Slider
                            value={sliderValue}
                            onValueChange={(newValue) => onChange(newValue[0])}
                            min={field.min || 0}
                            max={field.max || 100}
                            step={field.step || 1}
                            disabled={isDisabled}
                            className={cn(
                                error && "accent-destructive",
                                className
                            )}
                        />
                        <div className="flex justify-between text-xs text-muted-foreground">
                            <span>{field.min || 0}</span>
                            <span className="font-medium">{sliderValue[0]}</span>
                            <span>{field.max || 100}</span>
                        </div>
                    </div>
                );

            case "date":
            case "time":
            case "datetime-local":
                return (
                    <Input
                        {...commonProps}
                        type={field.type}
                        value={value || ""}
                        onChange={(e) => onChange(e.target.value)}
                    />
                );

            case "color":
                return (
                    <div className="flex items-center space-x-3">
                        <Input
                            {...commonProps}
                            type="color"
                            value={value || "#000000"}
                            onChange={(e) => onChange(e.target.value)}
                            className="w-12 h-10 p-1 rounded border cursor-pointer"
                        />
                        <Input
                            type="text"
                            value={value || ""}
                            onChange={(e) => onChange(e.target.value)}
                            placeholder="#000000"
                            className={cn(
                                "flex-1",
                                error && "border-destructive focus-visible:ring-destructive"
                            )}
                        />
                    </div>
                );

            case "file":
                return (
                    <Input
                        {...commonProps}
                        type="file"
                        accept={field.accept}
                        multiple={field.multiple}
                        onChange={(e) => {
                            const files = e.target.files;
                            onChange(field.multiple ? Array.from(files || []) : files?.[0] || null);
                        }}
                    />
                );

            default:
                return (
                    <Input
                        {...commonProps}
                        type="text"
                        value={value || ""}
                        onChange={(e) => onChange(e.target.value)}
                    />
                );
        }
    };

    return (
        <div className="space-y-2">
            {renderField()}
            {error && (
                <p className="text-sm font-medium text-destructive">{error}</p>
            )}
        </div>
    );
}