import React, { useEffect, useState, useRef, useCallback } from 'react';
import { API_URL } from '../config.ts';
import { authFetch } from '../utils/authFetch.ts';
import Wheel from '@uiw/react-color-wheel';

interface LightingState {
    power: string;
    red: number;
    blue: number;
    green: number;
    brightness: number;
}

export default function Lighting() {
    const [state, setState] = useState<LightingState>({ power: '', red: 0, blue: 0, green: 0, brightness: 100 });
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState('');
    const [success, setSuccess] = useState(false);
    const [pending, setPending] = useState(false);
    const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

    useEffect(() => {
        authFetch(`${API_URL}/lighting/state`)
            .then(res => res.json())
            .then(data => {
                setState(data);
                setLoading(false);
            })
            .catch(() => {
                setError('Failed to fetch lighting state');
                setLoading(false);
            });
    }, []);

    useEffect(() => {
        setState({ power: '', red: 0, blue: 0, green: 0, brightness: 100 });
    }, []);

    // Cleanup debounce on unmount
    useEffect(() => {
        return () => {
            if (debounceRef.current) {
                clearTimeout(debounceRef.current);
            }
        };
    }, []);

    // Consolidated debounced update function
    const updateLighting = useCallback((newState) => {
        setState(newState);
        setPending(true);
        setError('');
        setSuccess(false);

        // Clear any pending timeout
        if (debounceRef.current) {
            clearTimeout(debounceRef.current);
        }

        // Set new timeout for API call (250ms for smoother drag experience)
        debounceRef.current = setTimeout(() => {
            authFetch(`${API_URL}/lighting/state`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(newState),
            })
                .then(() => {
                    setSuccess(true);
                    setPending(false);
                })
                .catch(() => {
                    setError('Failed to update lighting state');
                    setPending(false);
                });
        }, 250);
    }, []);

    const handleSubmit = (e) => {
        e.preventDefault();
        setLoading(true);
        authFetch(`${API_URL}/lighting/state`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(state),
        })
            .then(() => setSuccess(true))
            .catch(() => setError('Failed to update lighting state'))
            .finally(() => setLoading(false));
    };

    const handlePowerToggle = () => {
        const newPower = state.power === 'on' ? 'off' : 'on';
        updateLighting({ ...state, power: newPower });
    };

    // Guard against undefined values
    const colorPreview = `rgb(${state.red ?? 0},${state.green ?? 0},${state.blue ?? 0})`;


    return (
        <div className="w-full min-h-[60vh] flex justify-center items-center mt-12 mb-12">
            <form
                onSubmit={handleSubmit}
                className="max-w-md w-full p-8 rounded-xl shadow bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 flex flex-col items-center justify-center"
                style={{ margin: '0 auto' }}
            >
                <h2 className="text-2xl font-bold mb-6 text-center text-neutral-800 dark:text-neutral-200">Lighting Controls</h2>

                <div className="flex items-center justify-between mb-8">
                    <span className="font-semibold text-lg mr-4">Power</span>
                    <label className="flex items-center gap-6 cursor-pointer select-none">
                        <div
                            className={`relative w-14 h-8 flex items-center bg-gray-300 dark:bg-gray-700 rounded-full p-1 transition-colors duration-300 ${state.power === 'on' ? 'bg-green-400' : 'bg-red-400'}`}
                            onClick={handlePowerToggle}
                            style={{ cursor: 'pointer' }}
                        >
                            <div
                                className={`absolute left-1 top-1 w-6 h-6 rounded-full bg-white shadow-md transition-transform duration-300`}
                                style={{ transform: state.power === 'on' ? 'translateX(24px)' : 'translateX(0)' }}
                            />
                        </div>
                        <span className={`text-base font-bold min-w-[48px] text-center ${state.power === 'on' ? 'text-green-700' : 'text-red-700'}`}>{state.power === 'on' ? 'On' : 'Off'}</span>
                    </label>
                </div>

                <div className="mb-8 flex flex-col items-center">
                    <label className="font-semibold mb-2">Color</label>
                    <div style={{
                        width: '180px',
                        height: '180px',
                        borderRadius: '1rem',
                        boxShadow: '0 2px 16px 0 #0002',
                        marginBottom: '1rem',
                        padding: '0',
                        overflow: 'hidden'
                    }}>
                        <Wheel
                            color={{ h: 0, s: 0, v: 100, a: 1 }}
                            onChange={(color) => {
                                const { h, s, v } = color.hsva;
                                // Convert percentages to decimals and handle undefined v
                                const { red, green, blue } = hsvToRgb(
                                    h / 360,           // hue: 0-360 -> 0-1
                                    s / 100,          // saturation: 0-100 -> 0-1
                                    (v ?? 100) / 100  // value: 0-100 -> 0-1, default to 1 if undefined
                                );
                                if (import.meta.env.DEV) console.debug('Converting color:', color.hsva, 'to RGB:', { red, green, blue });
                                // Auto power on when changing color
                                updateLighting({
                                    ...state,
                                    red,
                                    green,
                                    blue,
                                    power: state.power === 'off' ? 'on' : state.power
                                });
                            }}
                            width={180}
                            height={180}
                        />
                    </div>
                </div>
                <div className="mb-8 flex flex-col items-center w-full">
                    <label className="font-semibold mb-2" htmlFor="brightness">Brightness</label>
                    <input
                        id="brightness"
                        type="range"
                        min={0}
                        max={100}
                        value={state.brightness}
                        onChange={e => {
                            const newValue = Number(e.target.value);
                            // Auto power off at 0, auto power on when > 0
                            let newPower = state.power;
                            if (newValue === 0) {
                                newPower = 'off';
                            } else if (state.power === 'off' && newValue > 0) {
                                newPower = 'on';
                            }
                            updateLighting({
                                ...state,
                                brightness: newValue,
                                power: newPower
                            });
                        }}
                        className="w-full max-w-xs accent-yellow-500"
                    />
                    <span className="mt-2 text-sm font-bold text-yellow-700 dark:text-yellow-400">{state.brightness}</span>
                </div>

                <div className="flex flex-col items-center mb-8">
                    <span className="mb-2 text-sm text-neutral-700 dark:text-neutral-300">Live Color Preview</span>
                    <div
                        className="w-28 h-28 rounded-full border border-neutral-400 dark:border-neutral-700 shadow-xl transition-all duration-500"
                        style={{
                            background: state.power === 'on' ? colorPreview : 'linear-gradient(135deg, #222 60%, #444 100%)',
                            opacity: state.power === 'on' ? 1 : 0.3,
                            boxShadow: state.power === 'on' ? `0 0 32px 0 ${colorPreview}` : 'none',
                            outline: state.power === 'on' ? `2px solid ${colorPreview}` : '2px solid #333',
                            transition: 'background 0.3s, box-shadow 0.3s, outline 0.3s, opacity 0.3s',
                        }}
                    />
                </div>

                {error && <div className="mb-4 text-red-500 text-center font-bold animate-pulse">{error}</div>}
                {success && !pending && <div className="mb-4 text-green-600 text-center font-bold">Updated!</div>}
                {pending && <div className="mb-4 text-indigo-400 text-center text-sm">Syncing...</div>}
                {loading && <div className="mb-4 text-indigo-500 text-center font-bold animate-pulse">Loading...</div>}
            </form>
        </div>

    );
}

// Helper functions for color conversion
function rgbToHex(r, g, b) {
    r = typeof r === 'number' && !isNaN(r) ? r : 0;
    g = typeof g === 'number' && !isNaN(g) ? g : 0;
    b = typeof b === 'number' && !isNaN(b) ? b : 0;
    return (
        '#' +
        [r, g, b]
            .map(x => {
                const hex = x.toString(16);
                return hex.length === 1 ? '0' + hex : hex;
            })
            .join('')
    );
}

function hsvToRgb(h, s, v) {
    h = Math.max(0, Math.min(1, h));
    s = Math.max(0, Math.min(1, s));
    v = Math.max(0, Math.min(1, v));

    let r, g, b;
    const i = Math.floor(h * 6);
    const f = h * 6 - i;
    const p = v * (1 - s);
    const q = v * (1 - f * s);
    const t = v * (1 - (1 - f) * s);

    switch (i % 6) {
        case 0: r = v; g = t; b = p; break;
        case 1: r = q; g = v; b = p; break;
        case 2: r = p; g = v; b = t; break;
        case 3: r = p; g = q; b = v; break;
        case 4: r = t; g = p; b = v; break;
        case 5: r = v; g = p; b = q; break;
        default: r = 0; g = 0; b = 0;
    }

    return {
        red: Math.max(0, Math.min(255, Math.round(r * 255))),
        green: Math.max(0, Math.min(255, Math.round(g * 255))),
        blue: Math.max(0, Math.min(255, Math.round(b * 255)))
    };
}

function hexToRgb(hex) {
    hex = hex.replace('#', '');
    if (hex.length === 3) {
        hex = hex.split('').map(x => x + x).join('');
    }
    const num = parseInt(hex, 16);
    return {
        red: (num >> 16) & 255,
        green: (num >> 8) & 255,
        blue: num & 255,
    };
}
