/**
 * Color Picker Component
 * @since 1.3.0
 * @updated 1.6.0 - Added RGBA/opacity support
 */

import { useState, useEffect, useRef } from 'react'
import { t } from '@/lib/i18n'

interface ColorPickerProps {
    value: string
    onChange: (color: string) => void
    disabled?: boolean
    /** Show opacity slider for RGBA support */
    showOpacity?: boolean
}

// Convert RGB to hex
function rgbToHex(r: number, g: number, b: number): string {
    const toHex = (n: number) => {
        const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16)
        return hex.length === 1 ? '0' + hex : hex
    }
    return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}

// Parse any color format to get hex and opacity
function parseColor(color: string | undefined | null): { hex: string; opacity: number } {
    const safe = typeof color === 'string' ? color : ''
    // Handle rgba format
    const rgbaMatch = safe.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/)
    if (rgbaMatch) {
        const r = parseInt(rgbaMatch[1])
        const g = parseInt(rgbaMatch[2])
        const b = parseInt(rgbaMatch[3])
        const a = rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1
        return { hex: rgbToHex(r, g, b), opacity: a * 100 }
    }
    
    // Handle hex with alpha (#RRGGBBAA)
    const hexAlphaMatch = safe.match(/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i)
    if (hexAlphaMatch) {
        const hex = `#${hexAlphaMatch[1]}${hexAlphaMatch[2]}${hexAlphaMatch[3]}`
        const a = parseInt(hexAlphaMatch[4], 16) / 255
        return { hex, opacity: a * 100 }
    }
    
    // Handle standard hex
    if (/^#[0-9A-Fa-f]{6}$/.test(safe)) {
        return { hex: safe, opacity: 100 }
    }
    
    // Default
    return { hex: '#3BC2D0', opacity: 100 }
}

// Format color output based on opacity (uses 8-digit hex for alpha)
function formatColor(hex: string, opacity: number): string {
    if (opacity >= 100) {
        return hex
    }
    // Convert opacity to 2-digit hex (0-255)
    const alphaValue = Math.round((opacity / 100) * 255)
    const alphaHex = alphaValue.toString(16).padStart(2, '0')
    // Ensure hex is in proper format (strip existing alpha if present)
    const cleanHex = hex.replace(/^#/, '').slice(0, 6)
    return `#${cleanHex}${alphaHex}`.toUpperCase()
}

export function ColorPicker({ value, onChange, disabled = false, showOpacity = false }: ColorPickerProps) {
    const { hex: initialHex, opacity: initialOpacity } = parseColor(value)
    const [inputValue, setInputValue] = useState(initialHex)
    const [opacity, setOpacity] = useState(initialOpacity)
    const [showOpacityPopover, setShowOpacityPopover] = useState(false)
    const popoverRef = useRef<HTMLDivElement>(null)

    useEffect(() => {
        const { hex, opacity: parsedOpacity } = parseColor(value)
        setInputValue(hex)
        setOpacity(parsedOpacity)
    }, [value])

    // Close popover on click outside
    useEffect(() => {
        const handleClickOutside = (event: MouseEvent) => {
            if (popoverRef.current && !popoverRef.current.contains(event.target as Node)) {
                setShowOpacityPopover(false)
            }
        }
        document.addEventListener('mousedown', handleClickOutside)
        return () => document.removeEventListener('mousedown', handleClickOutside)
    }, [])

    const handleColorChange = (newColor: string) => {
        setInputValue(newColor)
        onChange(formatColor(newColor, opacity))
    }

    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const newValue = e.target.value
        setInputValue(newValue)

        // Handle 8-digit hex with alpha (#RRGGBBAA)
        const hexAlphaMatch = newValue.match(/^#([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/i)
        if (hexAlphaMatch) {
            // Parse alpha from the last 2 digits and update opacity
            const alphaHex = hexAlphaMatch[4]
            const alpha = parseInt(alphaHex, 16) / 255
            setInputValue(`#${hexAlphaMatch[1]}${hexAlphaMatch[2]}${hexAlphaMatch[3]}`)
            setOpacity(alpha * 100)
            onChange(newValue) // Pass the full 8-digit hex as-is
            return
        }

        // Handle standard 6-digit hex
        if (/^#[0-9A-Fa-f]{6}$/.test(newValue)) {
            onChange(formatColor(newValue, opacity))
        }
    }

    const handleOpacityChange = (newOpacity: number) => {
        setOpacity(newOpacity)
        onChange(formatColor(inputValue, newOpacity))
    }

    return (
        <div className="flex items-center gap-1.5 relative min-w-0" ref={popoverRef}>
            <div className="relative flex-shrink-0">
                <input
                    type="color"
                    value={inputValue || '#3BC2D0'}
                    onChange={(e) => handleColorChange(e.target.value)}
                    disabled={disabled}
                    className="w-10 h-9 rounded-md cursor-pointer border border-gray-300 disabled:opacity-50 disabled:cursor-not-allowed"
                />
                {showOpacity && opacity < 100 && (
                    <div 
                        className="absolute inset-0 pointer-events-none rounded-md border border-gray-300"
                        style={{
                            background: `linear-gradient(45deg, #ccc 25%, transparent 25%), linear-gradient(-45deg, #ccc 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ccc 75%), linear-gradient(-45deg, transparent 75%, #ccc 75%)`,
                            backgroundSize: '8px 8px',
                            backgroundPosition: '0 0, 0 4px, 4px -4px, -4px 0px',
                        }}
                    />
                )}
            </div>
            <input
                type="text"
                value={inputValue}
                onChange={handleInputChange}
                disabled={disabled}
                className="flex-1 min-w-0 px-2 py-1.5 border border-gray-300 rounded-md font-mono text-xs uppercase disabled:bg-gray-100 disabled:opacity-50"
                placeholder="#3BC2D0"
                maxLength={9}
                dir="ltr"
            />
            {showOpacity && (
                <>
                    <button
                        type="button"
                        onClick={() => setShowOpacityPopover(!showOpacityPopover)}
                        disabled={disabled}
                        className="flex-shrink-0 px-1.5 py-1.5 border border-gray-300 rounded-md text-[11px] font-mono hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap"
                        title={t('Opacity')}
                    >
                        {Math.round(opacity)}%
                    </button>
                    
                    {showOpacityPopover && (
                        <div className="absolute top-full left-0 mt-2 z-50 bg-white border border-gray-200 rounded-lg shadow-lg p-3 min-w-[200px]">
                            <label className="block text-xs font-medium text-gray-700 mb-2">
                                {t('Opacity')}
                            </label>
                            <div className="flex items-center gap-2">
                                <input
                                    type="range"
                                    min="0"
                                    max="100"
                                    value={opacity}
                                    onChange={(e) => handleOpacityChange(parseInt(e.target.value))}
                                    disabled={disabled}
                                    className="flex-1"
                                />
                                <input
                                    type="number"
                                    min="0"
                                    max="100"
                                    value={Math.round(opacity)}
                                    onChange={(e) => handleOpacityChange(parseInt(e.target.value) || 0)}
                                    disabled={disabled}
                                    className="w-14 px-2 py-1 border border-gray-300 rounded text-xs text-center"
                                />
                                <span className="text-xs text-gray-500">%</span>
                            </div>
                            <div className="mt-3 h-8 rounded border border-gray-200 relative overflow-hidden">
                                <div 
                                    className="absolute inset-0"
                                    style={{
                                        background: `linear-gradient(45deg, #ccc 25%, transparent 25%), linear-gradient(-45deg, #ccc 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ccc 75%), linear-gradient(-45deg, transparent 75%, #ccc 75%)`,
                                        backgroundSize: '10px 10px',
                                        backgroundPosition: '0 0, 0 5px, 5px -5px, -5px 0px',
                                    }}
                                />
                                <div 
                                    className="absolute inset-0"
                                    style={{ backgroundColor: formatColor(inputValue, opacity) }}
                                />
                            </div>
                        </div>
                    )}
                </>
            )}
        </div>
    )
}
