import { useState, useEffect } from "react"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Badge } from "@/components/ui/badge"
import { AlertCircle } from "lucide-react"
import { ProviderMetadata, ConfigFieldSchema, schemas } from "@/api/schema.gen"
import { DataSourceConfig } from "@/types/config"

interface DynamicConfigFormProps {
    metadata: ProviderMetadata;
    initialConfig: DataSourceConfig;
    onSave: (config: DataSourceConfig) => void;
    onTest: (config: DataSourceConfig) => void;
    isSaving: boolean;
    isTesting: boolean;
}

export function DynamicConfigForm({
    metadata,
    initialConfig,
    onSave,
    onTest,
    isSaving,
    isTesting
}: DynamicConfigFormProps) {
    const [config, setConfig] = useState<DataSourceConfig>(initialConfig);
    const [isDirty, setIsDirty] = useState(false);

    // Reset local state when initialConfig changes (e.g. after save or load)
    useEffect(() => {
        setConfig(initialConfig);
        setIsDirty(false);
    }, [initialConfig]);

    // Helper function to map PascalCase key (from Enum serialization) to snake_case key (DataSourceConfig struct)
    // Example: "ApiKey" -> "api_key", "ApiUrl" -> "api_url"
    const mapKeyToConfigField = (key: string): keyof DataSourceConfig => {
        // Simple mapping: convert to snake_case.
        // Since we know the keys are things like "ApiKey", "ApiToken" (which maps to api_key usually?)
        // Wait, DataSourceConfig has `api_key`, `api_url`.
        // ConfigKey enum has `ApiKey`, `ApiUrl`, `ApiToken`.
        // `ApiToken` usually maps to `api_key` in our `DataSourceConfig` struct (as seen in main.rs mapping comment).
        
        // Manual mapping based on knowledge of DataSourceConfig structure
        // If the key is unknown/unmapped, we try to use it as is or lowercase it.
        switch (key) {
            case "ApiKey": return "api_key";
            case "ApiToken": return "api_key"; // Tushare uses ApiToken but stores in api_key
            case "ApiUrl": return "api_url";
            case "BaseUrl": return "api_url"; // Maybe?
            default: 
                // Fallback: try snake case conversion or just lowercase
                return key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`).replace(/^_/, "") as keyof DataSourceConfig;
        }
    }

    // Generic handler for field updates
    const handleChange = (fieldKey: string, value: any) => {
        const configField = mapKeyToConfigField(fieldKey);
        setConfig(prev => ({ ...prev, [configField]: value }));
        setIsDirty(true);
    }

    const renderField = (fieldSchema: ConfigFieldSchema) => {
        // fieldSchema.key is the Enum string (e.g. "ApiKey")
        const configField = mapKeyToConfigField(fieldSchema.key as string);
        
        // Access the config value using the mapped key
        const currentValue = (config as any)[configField] || "";
        const isEnabled = config.enabled;

        switch (fieldSchema.field_type) {
            case schemas.FieldType.enum.Boolean:
                return (
                    <div className="flex items-center justify-between" key={fieldSchema.key}>
                        <Label htmlFor={fieldSchema.key}>{fieldSchema.label}</Label>
                        <Switch
                            id={fieldSchema.key}
                            checked={currentValue === true}
                            onCheckedChange={(checked) => handleChange(fieldSchema.key, checked)}
                            disabled={!isEnabled}
                        />
                    </div>
                );
            case schemas.FieldType.enum.Select:
                return (
                    <div className="space-y-2" key={fieldSchema.key}>
                        <Label htmlFor={fieldSchema.key}>{fieldSchema.label}</Label>
                        <Select
                            value={currentValue}
                            onValueChange={(val) => handleChange(fieldSchema.key, val)}
                            disabled={!isEnabled}
                        >
                            <SelectTrigger id={fieldSchema.key}>
                                <SelectValue placeholder={fieldSchema.placeholder || "Select..."} />
                            </SelectTrigger>
                            <SelectContent>
                                {fieldSchema.options?.map(opt => (
                                    <SelectItem key={opt} value={opt}>{opt}</SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                        {fieldSchema.description && <p className="text-sm text-muted-foreground">{fieldSchema.description}</p>}
                    </div>
                );
            case schemas.FieldType.enum.Password:
                return (
                    <div className="space-y-2" key={fieldSchema.key}>
                        <Label htmlFor={fieldSchema.key}>{fieldSchema.label}</Label>
                        <Input
                            id={fieldSchema.key}
                            type="password"
                            value={currentValue}
                            onChange={(e) => handleChange(fieldSchema.key, e.target.value)}
                            placeholder={fieldSchema.placeholder || ""}
                            disabled={!isEnabled}
                        />
                        {fieldSchema.description && <p className="text-sm text-muted-foreground">{fieldSchema.description}</p>}
                    </div>
                );
            default: // Text, Url
                return (
                    <div className="space-y-2" key={fieldSchema.key}>
                        <Label htmlFor={fieldSchema.key}>{fieldSchema.label}</Label>
                        <Input
                            id={fieldSchema.key}
                            type="text"
                            value={currentValue}
                            onChange={(e) => handleChange(fieldSchema.key, e.target.value)}
                            placeholder={fieldSchema.placeholder || ""}
                            disabled={!isEnabled}
                        />
                        {fieldSchema.description && <p className="text-sm text-muted-foreground">{fieldSchema.description}</p>}
                    </div>
                );
        }
    }

    return (
        <Card className={config.enabled ? "border-primary/50 bg-accent/5" : "opacity-80"}>
            <CardHeader className="flex flex-row items-start justify-between pb-2">
                <div className="space-y-1">
                    <CardTitle className="text-xl flex items-center gap-2">
                        {metadata.name_cn || metadata.name_en}
                        {config.enabled ?
                            <Badge variant="default" className="bg-green-600 hover:bg-green-600 h-5 text-[10px]">Active</Badge> :
                            <Badge variant="outline" className="text-muted-foreground h-5 text-[10px]">Inactive</Badge>
                        }
                    </CardTitle>
                    <CardDescription>{metadata.description}</CardDescription>
                </div>
                <Switch
                    checked={config.enabled}
                    onCheckedChange={(checked) => handleChange('enabled', checked)}
                />
            </CardHeader>
            <CardContent className="space-y-4">
                {metadata.config_schema.map(field => renderField(field))}
            </CardContent>
            <CardFooter className="flex justify-between pt-0">
                <Button
                    variant="outline"
                    size="sm"
                    disabled={!config.enabled || isTesting || !metadata.supports_test_connection}
                    onClick={() => onTest(config)}
                >
                    {isTesting ? <span className="animate-spin mr-2">⏳</span> : <AlertCircle className="mr-2 h-4 w-4" />}
                    测试连接
                </Button>
                <Button
                    size="sm"
                    disabled={!isDirty || isSaving}
                    onClick={() => onSave(config)}
                >
                    {isSaving ? "保存中..." : "保存"}
                </Button>
            </CardFooter>
        </Card>
    )
}
