import React, { useState, useEffect, useMemo } from 'react';
import {
    Save,
    Edit2,
    Loader2,
    Search,
    Type,
    Hash,
    Calendar,
    List,
    ToggleLeft,
    Copy,
    Check,
    X,
    Database
} from 'lucide-react';
import { format } from 'date-fns';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    Tooltip,
    TooltipContent,
    TooltipProvider,
    TooltipTrigger,
} from '@/components/ui/tooltip';
import { useCustomFields, useContactCustomValues } from '@/hooks/useContact';
import { Tables } from '@/integrations/supabase/types';
import { cn } from '@/lib/utils';
import { toast } from 'sonner';

type CustomField = Tables<'custom_fields'>;

interface ContactCustomFieldsTabProps {
    contactId: string;
}

const FieldIcon = ({ type }: { type: string }) => {
    switch (type) {
        case 'number': return <Hash className="h-4 w-4 text-blue-500" />;
        case 'date': return <Calendar className="h-4 w-4 text-purple-500" />;
        case 'boolean': return <ToggleLeft className="h-4 w-4 text-green-500" />;
        case 'select': return <List className="h-4 w-4 text-orange-500" />;
        default: return <Type className="h-4 w-4 text-slate-500" />;
    }
};

export function ContactCustomFieldsTab({ contactId }: ContactCustomFieldsTabProps) {
    const { data: customFields = [], isLoading: fieldsLoading } = useCustomFields();
    const { values: customValues, isLoading: valuesLoading, saveValues, isSaving } = useContactCustomValues(contactId);

    const [isEditing, setIsEditing] = useState(false);
    const [editValues, setEditValues] = useState<Record<string, string>>({});
    const [searchQuery, setSearchQuery] = useState('');

    // Build a map of current values for easy access
    const valuesMap = useMemo(() => {
        const map: Record<string, string> = {};
        customValues.forEach((cv) => {
            map[cv.custom_field_id] = cv.value ?? '';
        });
        return map;
    }, [customValues]);

    // Sync edit state when entering edit mode
    useEffect(() => {
        if (isEditing) {
            setEditValues(valuesMap);
        }
    }, [isEditing, valuesMap]);

    // Filter fields based on search
    const filteredFields = useMemo(() => {
        if (!searchQuery) return customFields;
        return customFields.filter(f =>
            f.label.toLowerCase().includes(searchQuery.toLowerCase())
        );
    }, [customFields, searchQuery]);

    const handleValueChange = (fieldId: string, value: string) => {
        setEditValues((prev) => ({ ...prev, [fieldId]: value }));
    };

    const handleSave = async () => {
        try {
            await saveValues(editValues);
            toast.success('Custom fields updated');
            setIsEditing(false);
        } catch (error) {
            toast.error('Failed to save changes');
        }
    };

    const handleCancel = () => {
        setEditValues(valuesMap);
        setIsEditing(false);
    };

    const copyToClipboard = (text: string, label: string) => {
        if (!text) return;
        navigator.clipboard.writeText(text);
        toast.success(`${label} copied`);
    };

    const isLoading = fieldsLoading || valuesLoading;

    if (isLoading) {
        return (
            <div className="flex flex-col items-center justify-center h-48 space-y-3">
                <Loader2 className="h-8 w-8 animate-spin text-primary/50" />
                <p className="text-sm text-muted-foreground">Loading custom data...</p>
            </div>
        );
    }

    return (
        <div className="flex flex-col h-full space-y-4">
            {/* Header Toolbar */}
            <div className="flex items-center justify-between gap-4">
                <div className="flex items-center gap-2">
                    <Database className="h-5 w-5 text-muted-foreground" />
                    <h3 className="text-lg font-semibold text-foreground">Additional Data</h3>
                    <Badge variant="outline" className="ml-2">
                        {customFields.length}
                    </Badge>
                </div>

                <div className="flex items-center gap-2 flex-1 justify-end">
                    {!isEditing && (
                        <div className="relative w-full max-w-[200px] hidden sm:block">
                            <Search className="absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
                            <Input
                                placeholder="Search fields..."
                                value={searchQuery}
                                onChange={(e) => setSearchQuery(e.target.value)}
                                className="h-8 pl-8 text-xs bg-muted/30 border-transparent focus:bg-background focus:border-border transition-all"
                            />
                        </div>
                    )}

                    {isEditing ? (
                        <div className="flex gap-2 animate-in fade-in slide-in-from-right-2">
                            <Button variant="ghost" size="sm" onClick={handleCancel} disabled={isSaving} className="h-8">
                                Cancel
                            </Button>
                            <Button size="sm" onClick={handleSave} disabled={isSaving} className="h-8 gap-1.5 min-w-[80px]">
                                {isSaving ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Save className="h-3.5 w-3.5" />}
                                Save
                            </Button>
                        </div>
                    ) : (
                        <Button variant="outline" size="sm" onClick={() => setIsEditing(true)} className="h-8 gap-2">
                            <Edit2 className="h-3.5 w-3.5" />
                            Edit Fields
                        </Button>
                    )}
                </div>
            </div>

            {/* Main Content Area */}
            <div className="flex-1 min-h-0 bg-card rounded-lg border shadow-sm overflow-hidden">
                {customFields.length === 0 ? (
                    <div className="flex flex-col items-center justify-center h-48 text-center p-6">
                        <div className="h-12 w-12 rounded-full bg-muted flex items-center justify-center mb-3">
                            <Database className="h-6 w-6 text-muted-foreground/50" />
                        </div>
                        <h4 className="font-medium text-sm">No custom fields configured</h4>
                        <p className="text-xs text-muted-foreground mt-1 max-w-[250px]">
                            Go to Settings to define custom data fields for your contacts.
                        </p>
                    </div>
                ) : (
                    <ScrollArea className="h-full">
                        <div className="p-4 grid grid-cols-1 md:grid-cols-2 gap-4">
                            {filteredFields.map((field) => {
                                const value = isEditing
                                    ? (editValues[field.id] ?? '')
                                    : (valuesMap[field.id] ?? '');

                                return (
                                    <div
                                        key={field.id}
                                        className={cn(
                                            "p-3 rounded-md border transition-all duration-200",
                                            isEditing
                                                ? "bg-background border-primary/20 ring-1 ring-primary/5 shadow-sm"
                                                : "bg-muted/10 border-transparent hover:bg-muted/30 hover:border-border/50 group"
                                        )}
                                    >
                                        {/* Label Header */}
                                        <div className="flex items-center gap-2 mb-2">
                                            <div className="p-1 rounded bg-background border shadow-sm">
                                                <FieldIcon type={field.field_type} />
                                            </div>
                                            <Label className={cn(
                                                "text-xs font-medium uppercase tracking-wider",
                                                isEditing ? "text-primary" : "text-muted-foreground"
                                            )}>
                                                {field.label}
                                            </Label>
                                        </div>

                                        {/* Field Content */}
                                        <div className="pl-8">
                                            {isEditing ? (
                                                <EditFieldInput
                                                    field={field}
                                                    value={value}
                                                    onChange={(v) => handleValueChange(field.id, v)}
                                                />
                                            ) : (
                                                <ViewFieldValue
                                                    field={field}
                                                    value={value}
                                                    onCopy={() => copyToClipboard(value, field.label)}
                                                />
                                            )}
                                        </div>
                                    </div>
                                );
                            })}

                            {filteredFields.length === 0 && searchQuery && (
                                <div className="col-span-full py-8 text-center text-sm text-muted-foreground">
                                    No fields match "{searchQuery}"
                                </div>
                            )}
                        </div>
                    </ScrollArea>
                )}
            </div>
        </div>
    );
}

// ------------------------------------------------------------------
// Sub-components to keep the main file clean and readable
// ------------------------------------------------------------------

function ViewFieldValue({ field, value, onCopy }: { field: CustomField; value: string; onCopy: () => void }) {
    if (!value) {
        return <span className="text-sm text-muted-foreground/40 italic">-- Empty --</span>;
    }

    let content: React.ReactNode = value;

    // Type-specific rendering
    if (field.field_type === 'boolean') {
        const isTrue = value === 'true';
        content = (
            <Badge variant={isTrue ? "default" : "secondary"} className={cn(
                "px-2 py-0 h-5 text-[10px] gap-1",
                isTrue ? "bg-emerald-500 hover:bg-emerald-600" : ""
            )}>
                {isTrue ? <Check className="h-3 w-3" /> : <X className="h-3 w-3" />}
                {isTrue ? 'Yes' : 'No'}
            </Badge>
        );
    } else if (field.field_type === 'date') {
        const date = new Date(value);
        content = !isNaN(date.getTime()) ? (
            <span className="font-mono text-sm">{format(date, 'MMM d, yyyy')}</span>
        ) : value;
    } else if (field.field_type === 'number') {
        content = <span className="font-mono text-sm">{value}</span>;
    } else {
        content = <span className="text-sm font-medium break-all">{value}</span>;
    }

    return (
        <div className="flex items-center justify-between group/val">
            <div>{content}</div>
            {field.field_type !== 'boolean' && (
                <TooltipProvider>
                    <Tooltip>
                        <TooltipTrigger asChild>
                            <Button
                                variant="ghost"
                                size="icon"
                                className="h-6 w-6 opacity-0 group-hover/val:opacity-100 transition-opacity"
                                onClick={onCopy}
                            >
                                <Copy className="h-3 w-3 text-muted-foreground" />
                            </Button>
                        </TooltipTrigger>
                        <TooltipContent side="left">Copy value</TooltipContent>
                    </Tooltip>
                </TooltipProvider>
            )}
        </div>
    );
}

function EditFieldInput({
    field,
    value,
    onChange
}: {
    field: CustomField;
    value: string;
    onChange: (val: string) => void
}) {
    const options = Array.isArray(field.options) ? field.options as string[] : [];

    switch (field.field_type) {
        case 'select':
            return (
                <Select value={value} onValueChange={onChange}>
                    <SelectTrigger className="h-8 text-sm bg-muted/20">
                        <SelectValue placeholder="Select..." />
                    </SelectTrigger>
                    <SelectContent>
                        {options.map((opt) => (
                            <SelectItem key={opt} value={opt}>{opt}</SelectItem>
                        ))}
                    </SelectContent>
                </Select>
            );

        case 'boolean':
            return (
                <div className="flex items-center h-8">
                    <Switch
                        checked={value === 'true'}
                        onCheckedChange={(checked) => onChange(checked ? 'true' : 'false')}
                    />
                    <span className="ml-2 text-xs text-muted-foreground">
                        {value === 'true' ? 'True' : 'False'}
                    </span>
                </div>
            );

        case 'date':
            return (
                <Input
                    type="date"
                    value={value}
                    onChange={(e) => onChange(e.target.value)}
                    className="h-8 text-sm bg-muted/20"
                />
            );

        case 'number':
            return (
                <Input
                    type="number"
                    value={value}
                    onChange={(e) => onChange(e.target.value)}
                    className="h-8 text-sm bg-muted/20 font-mono"
                    placeholder="0.00"
                />
            );

        default:
            return (
                <Input
                    type="text"
                    value={value}
                    onChange={(e) => onChange(e.target.value)}
                    className="h-8 text-sm bg-muted/20"
                    placeholder="Enter value..."
                />
            );
    }
}