import { Input } from '@/components/ui/input';
import { Plus, Trash2 } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';

interface Pair {
    key: string;
    value: string;
}

interface Props {
    value: Record<string, string> | null | undefined;
    onChange: (data: Record<string, string> | null) => void;
    placeholder?: { key?: string; value?: string };
    hint?: string;
    readonlyKeys?: boolean;
}

function objectToPairs(obj: Record<string, any> | null | undefined): Pair[] {
    if (!obj || typeof obj !== 'object') return [{ key: '', value: '' }];
    const entries = Object.entries(obj);
    return entries.length ? entries.map(([k, v]) => ({ key: k, value: String(v) })) : [{ key: '', value: '' }];
}

function pairsToObject(pairs: Pair[]): Record<string, string> | null {
    const filled = pairs.filter((p) => p.key.trim() !== '');
    if (filled.length === 0) return null;
    const obj: Record<string, string> = {};
    filled.forEach((p) => { obj[p.key.trim()] = p.value; });
    return obj;
}

export function KeyValueEditor({ value, onChange, placeholder, hint, readonlyKeys = false }: Props) {
    // Internal pairs state — drives the UI. Empty rows are kept for display.
    const [pairs, setPairs] = useState<Pair[]>(() => objectToPairs(value));

    // Sync inward only when value identity changes (e.g. initial load from server).
    // We track the last value we sent out so we don't re-sync our own emits.
    const lastEmitted = useRef<Record<string, string> | null>(null);
    useEffect(() => {
        if (value === lastEmitted.current) return;
        setPairs(objectToPairs(value));
    }, [value]);

    const emit = (next: Pair[]) => {
        const obj = pairsToObject(next);
        lastEmitted.current = obj;
        onChange(obj);
    };

    const updatePair = (index: number, field: 'key' | 'value', val: string) => {
        const next = pairs.map((p, i) => (i === index ? { ...p, [field]: val } : p));
        setPairs(next);
        emit(next);
    };

    const addRow = () => {
        setPairs((prev) => [...prev, { key: '', value: '' }]);
        // nothing to emit yet — the new row is empty
    };

    const removeRow = (index: number) => {
        const next = pairs.length > 1 ? pairs.filter((_, i) => i !== index) : [{ key: '', value: '' }];
        setPairs(next);
        emit(next);
    };

    return (
        <div className="space-y-2">
            <div className="overflow-hidden rounded-lg border border-[#d8d8d8]">
                {/* Header */}
                <div className={`grid border-b border-[#e3e3e3] bg-[#fafafa] px-3 py-2 ${readonlyKeys ? 'grid-cols-2' : 'grid-cols-[1fr_1fr_32px]'}`}>
                    <span className="text-xs font-medium uppercase tracking-wide text-[#6d7175]">Key</span>
                    <span className="text-xs font-medium uppercase tracking-wide text-[#6d7175]">Value</span>
                    {!readonlyKeys && <span />}
                </div>

                {/* Rows */}
                <div className="divide-y divide-[#efefef]">
                    {pairs.map((pair, idx) => (
                        <div key={idx} className={`grid items-center ${readonlyKeys ? 'grid-cols-2' : 'grid-cols-[1fr_1fr_32px]'}`}>
                            <div className="border-r border-[#efefef] px-2 py-1.5">
                                <Input
                                    value={pair.key}
                                    onChange={(e) => updatePair(idx, 'key', e.target.value)}
                                    placeholder={placeholder?.key ?? 'e.g. api_key'}
                                    readOnly={readonlyKeys}
                                    className={`h-8 border-0 px-1 text-sm shadow-none focus-visible:ring-0 ${readonlyKeys ? 'bg-[#f6f6f7] text-[#6d7175] cursor-default select-none' : 'bg-transparent'}`}
                                />
                            </div>
                            <div className="px-2 py-1.5">
                                <Input
                                    value={pair.value}
                                    onChange={(e) => updatePair(idx, 'value', e.target.value)}
                                    placeholder={placeholder?.value ?? 'value'}
                                    className="h-8 border-0 bg-transparent px-1 text-sm shadow-none focus-visible:ring-0"
                                />
                            </div>
                            {!readonlyKeys && (
                                <div className="flex items-center justify-center pr-1">
                                    <button
                                        type="button"
                                        onClick={() => removeRow(idx)}
                                        className="flex h-6 w-6 items-center justify-center rounded text-gray-400 transition-colors hover:bg-red-50 hover:text-red-500"
                                    >
                                        <Trash2 className="h-3.5 w-3.5" />
                                    </button>
                                </div>
                            )}
                        </div>
                    ))}
                </div>

                {/* Add row footer — hidden when keys are readonly */}
                {!readonlyKeys && (
                    <div className="border-t border-[#e3e3e3] bg-[#fafafa] px-3 py-1.5">
                        <button
                            type="button"
                            onClick={addRow}
                            className="flex items-center gap-1 text-xs font-medium text-[#008060] hover:text-[#006b51]"
                        >
                            <Plus className="h-3.5 w-3.5" />
                            Add row
                        </button>
                    </div>
                )}
            </div>

            {hint && <p className="text-xs text-[#6d7175]">{hint}</p>}
        </div>
    );
}
