import { useState, useEffect, useCallback } from 'react'
import { Field } from '../../../../types'
import { Checkbox } from '@/components/ui/checkbox'
import { cn } from '@/lib/utils'
import React from 'react'

interface CheckboxCellProps<T extends string> {
  field: Field<T>
  value: any
  onChange: (value: any) => void
  hasErrors?: boolean
  booleanMatches?: Record<string, boolean>
  className?: string
}

const CheckboxCell = <T extends string>({
  field,
  value,
  onChange,
  hasErrors,
  booleanMatches = {},
  className = ''
}: CheckboxCellProps<T>) => {
  const [checked, setChecked] = useState(false)
  // Add state for hover
  const [isHovered, setIsHovered] = useState(false)
  
  // Initialize checkbox state
  useEffect(() => {
    if (value === undefined || value === null) {
      setChecked(false)
      return
    }
    
    if (typeof value === 'boolean') {
      setChecked(value)
      return
    }
    
    // Handle string values using booleanMatches
    if (typeof value === 'string') {
      // First try the field's booleanMatches
      const fieldBooleanMatches = field.fieldType.type === 'checkbox' 
        ? field.fieldType.booleanMatches || {}
        : {}
        
      // Merge with the provided booleanMatches, with the provided ones taking precedence
      const allMatches = { ...fieldBooleanMatches, ...booleanMatches }
      
      // Try to find the value in the matches
      const matchEntry = Object.entries(allMatches).find(([k]) => 
        k.toLowerCase() === value.toLowerCase())
      
      if (matchEntry) {
        setChecked(matchEntry[1])
        return
      }
      
      // If no match found, use common true/false strings
      const trueStrings = ['yes', 'true', '1', 'y']
      const falseStrings = ['no', 'false', '0', 'n']
      
      if (trueStrings.includes(value.toLowerCase())) {
        setChecked(true)
        return
      }
      
      if (falseStrings.includes(value.toLowerCase())) {
        setChecked(false)
        return
      }
    }
    
    // For any other values, try to convert to boolean
    setChecked(!!value)
  }, [value, field.fieldType, booleanMatches])
  
  // Helper function to check if a class is present in the className string
  const hasClass = (cls: string): boolean => {
    const classNames = (className || '').split(' ');
    return classNames.includes(cls);
  };
  
  // Handle checkbox change
  const handleChange = useCallback((checked: boolean) => {
    setChecked(checked)
    onChange(checked)
  }, [onChange])
  
  // Add outline even when not in focus
  const outlineClass = "border focus-visible:ring-0 focus-visible:ring-offset-0"
  
  return (
    <div 
      className={cn(
        "flex items-center justify-center h-10 px-2 py-1 rounded-md",
        outlineClass,
        hasErrors ? "bg-red-50 border-destructive" : "border-input",
        className
      )}
      style={{
        backgroundColor: hasClass('!bg-blue-100') ? '#dbeafe' : 
                        hasClass('!bg-blue-200') ? '#bfdbfe' : 
                        hasClass('hover:!bg-blue-100') && isHovered ? '#dbeafe' :
                        undefined,
        borderColor: hasClass('!border-blue-500') ? '#3b82f6' : 
                    hasClass('!border-blue-200') ? '#bfdbfe' : 
                    hasClass('!border-blue-200') && isHovered ? '#bfdbfe' :
                    undefined,
        borderRadius: hasClass('!rounded-md') ? '0.375rem' : undefined
      }}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
    >
      <Checkbox
        checked={checked}
        onCheckedChange={handleChange}
        className={cn(
          hasErrors ? "border-destructive" : ""
        )}
      />
    </div>
  )
}

export default React.memo(CheckboxCell, (prev, next) => {
  if (prev.hasErrors !== next.hasErrors) return false;
  if (prev.field !== next.field) return false;
  if (prev.value !== next.value) return false;
  if (prev.className !== next.className) return false;
  
  // Compare booleanMatches objects
  const prevMatches = prev.booleanMatches || {};
  const nextMatches = next.booleanMatches || {};
  const prevKeys = Object.keys(prevMatches);
  const nextKeys = Object.keys(nextMatches);
  
  if (prevKeys.length !== nextKeys.length) return false;
  
  for (const key of prevKeys) {
    if (prevMatches[key] !== nextMatches[key]) return false;
  }
  
  return true;
}); 