import React, { useState, useRef, useEffect, forwardRef } from 'react'
import { createCalculator } from '@/util/calc-utils'
import '@/styles/calc.scss'

export const CalculatorInput = forwardRef(
  ({ value, onChange, label, options = {}, id, className = 'calculator-input', readOnly = false, placeholder, name='', disabled = false }, ref) => {
    const [showKeypad, setShowKeypad] = useState(false)
    const [displayValue, setDisplayValue] = useState(value || '0')
    const [hasOperation, setHasOperation] = useState(false)
    const calculatorRef = useRef(createCalculator(options))
    const containerRef = useRef(null)
    const inputRef = useRef(null)

    // 외부 ref와 내부 ref를 동기화
    useEffect(() => {
      if (ref) {
        if (typeof ref === 'function') {
          ref(inputRef.current)
        } else {
          ref.current = inputRef.current
        }
      }
    }, [ref])

    // Sync displayValue with value prop
    useEffect(() => {
      setDisplayValue(value || '0')
    }, [value])

    // 클릭 외부 감지
    useEffect(() => {
      const handleClickOutside = (event) => {
        if (containerRef.current && !containerRef.current.contains(event.target)) {
          setShowKeypad(false)
          if (hasOperation) {
            // If there's an operation in progress, compute the result when losing focus
            handleCompute()
          }
        }
      }

      document.addEventListener('mousedown', handleClickOutside)
      return () => document.removeEventListener('mousedown', handleClickOutside)
    }, [value, onChange, hasOperation])

    // 숫자 입력 처리 함수 수정
    const handleNumber = (num) => {
      const calculator = calculatorRef.current
      let newDisplayValue = ''

      // 소수점 이하 2자리 제한 로직 추가
      const shouldPreventInput = (value) => {
        const decimalParts = (value || '').split('.')
        return decimalParts.length > 1 && decimalParts[1].length >= 2
      }

      if (hasOperation) {
        // 연산자 이후 숫자 입력 시
        if (calculator.currentOperand === '0' || calculator.shouldResetDisplay) {
          calculator.currentOperand = num.toString()
          calculator.shouldResetDisplay = false
        }else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
          calculator.currentOperand = (calculator.currentOperand || '') + num
        }
        // else {
        //   calculator.currentOperand = (calculator.currentOperand || '') + num
        // }
        newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
        setDisplayValue(newDisplayValue)
      } else {
        // 첫 번째 숫자 입력 시
        if (displayValue === '0' || calculator.shouldResetDisplay) {
          calculator.currentOperand = num.toString()
          calculator.shouldResetDisplay = false
          newDisplayValue = calculator.currentOperand
          setDisplayValue(newDisplayValue)
          if (!hasOperation) {
            onChange(calculator.currentOperand)
          }
        } else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
          calculator.currentOperand = (calculator.currentOperand || '') + num
          newDisplayValue = calculator.currentOperand
          setDisplayValue(newDisplayValue)
          if (!hasOperation) {
            onChange(newDisplayValue)
          }
        }
        // else {
        //   calculator.currentOperand = (calculator.currentOperand || '') + num
        //   newDisplayValue = calculator.currentOperand
        //   setDisplayValue(newDisplayValue)
        //   if (!hasOperation) {
        //     onChange(newDisplayValue)
        //   }
        // }
      }

      // 커서를 텍스트 끝으로 이동하고 스크롤 처리
      requestAnimationFrame(() => {
        if (inputRef.current) {
          inputRef.current.focus()
          const len = newDisplayValue.length
          inputRef.current.setSelectionRange(len, len)
          // 텍스트 끝으로 스크롤
          inputRef.current.scrollLeft = inputRef.current.scrollWidth
        }
      })
    }

    // 연산자 처리 함수 수정
    const handleOperation = (operation) => {
      const calculator = calculatorRef.current
      let newDisplayValue = ''

      // 현재 입력된 값이 없으면 이전 값 사용 (연속 연산 시)
      if (!calculator.currentOperand && calculator.previousOperand) {
        calculator.operation = operation
        newDisplayValue = calculator.previousOperand + operation
        setDisplayValue(newDisplayValue)
        setHasOperation(true)
      } else if (hasOperation) {
        // 이미 연산자가 있는 경우, 계산 실행
        const result = calculator.compute()
        if (result !== undefined) {
          calculator.previousOperand = result.toString()
          calculator.operation = operation
          calculator.currentOperand = ''
          newDisplayValue = calculator.previousOperand + operation
          setDisplayValue(newDisplayValue)
        }
      } else {
        // 첫 번째 연산자 입력 시
        calculator.previousOperand = calculator.currentOperand || '0'
        calculator.operation = operation
        calculator.currentOperand = ''
        setHasOperation(true)
        newDisplayValue = calculator.previousOperand + operation
        setDisplayValue(newDisplayValue)
      }

      // 커서를 텍스트 끝으로 이동하고 스크롤 처리
      requestAnimationFrame(() => {
        if (inputRef.current) {
          inputRef.current.focus()
          const len = newDisplayValue.length
          inputRef.current.setSelectionRange(len, len)
          // 텍스트 끝으로 스크롤
          inputRef.current.scrollLeft = inputRef.current.scrollWidth
        }
      })
    }

    // AC 버튼 클릭 핸들러
    const handleClear = () => {
      const calculator = calculatorRef.current
      const newValue = calculator.clear()
      const displayValue = newValue || '0'
      setDisplayValue(displayValue)
      setHasOperation(false)
      onChange(displayValue)
      // 커서를 텍스트 끝으로 이동하고 스크롤 처리
      requestAnimationFrame(() => {
        if (inputRef.current) {
          inputRef.current.focus()
          const len = displayValue.length
          inputRef.current.setSelectionRange(len, len)
          // 텍스트 끝으로 스크롤
          inputRef.current.scrollLeft = inputRef.current.scrollWidth
        }
      })
    }

    // 계산 실행 함수 수정
    const handleCompute = (fromEnterKey = false) => {
      const calculator = calculatorRef.current
      if (!hasOperation || !calculator.currentOperand) return

      const result = calculator.compute()
      if (result !== undefined) {
        const resultStr = result.toString()
        setDisplayValue(resultStr)
        setHasOperation(false)
        // Only call onChange with the final result
        onChange(resultStr)

        // 엔터키로 호출된 경우 포커스 설정하지 않음
        if (!fromEnterKey) {
          requestAnimationFrame(() => {
            if (inputRef.current) {
              inputRef.current.focus()
              const len = resultStr.length
              inputRef.current.setSelectionRange(len, len)
            }
          })
        }
      }
    }

    // DEL 버튼 클릭 핸들러
    const handleDelete = () => {
      const calculator = calculatorRef.current
      const newValue = calculator.deleteNumber()
      const displayValue = newValue || '0'
      setDisplayValue(displayValue)
      setHasOperation(!!calculator.operation)
      onChange(displayValue)
      // 커서를 텍스트 끝으로 이동하고 스크롤 처리
      requestAnimationFrame(() => {
        if (inputRef.current) {
          inputRef.current.focus()
          const len = displayValue.length
          inputRef.current.setSelectionRange(len, len)
          // 텍스트 끝으로 스크롤
          inputRef.current.scrollLeft = inputRef.current.scrollWidth
        }
      })
    }

    // input의 onChange 이벤트 처리 - 허용된 계산기 입력만 처리
    const handleInputChange = (e) => {
      if (readOnly) return

      const inputValue = e.target.value

      // 허용된 문자만 필터링 (숫자, 연산자, 소수점)
      const filteredValue = inputValue.replace(/[^0-9+\-×÷.]/g, '')

      // 연산자 연속 입력 방지
      const lastChar = filteredValue[filteredValue.length - 1]
      const prevChar = filteredValue[filteredValue.length - 2]

      if (['+', '×', '÷'].includes(lastChar) && ['+', '-', '×', '÷', '.'].includes(prevChar)) {
        // 연산자나 소수점이 연속으로 입력된 경우 이전 문자 유지
        return
      }

      // 소수점 중복 입력 방지
      const parts = filteredValue.split(/[+\-×÷]/)
      if (parts[parts.length - 1].split('.').length > 2) {
        // 한 숫자에 소수점이 2개 이상인 경우
        return
      }

      setDisplayValue(filteredValue)

      // 계산기 상태 업데이트
      if (filteredValue !== displayValue) {
        const calculator = calculatorRef.current
        const hasOperation = /[+\-×÷]/.test(filteredValue)

        if (hasOperation) {
          const [operand1, operator, operand2] = filteredValue.split(/([+\-×÷])/)
          calculator.previousOperand = operand1 || ''
          calculator.operation = operator || ''
          calculator.currentOperand = operand2 || ''
          setHasOperation(true)
        } else {
          calculator.currentOperand = filteredValue
          setHasOperation(false)
        }

        onChange(filteredValue)
      }
    }

    // 키패드 토글 함수
    const toggleKeypad = (e) => {
      if (e) {
        e.preventDefault()
        e.stopPropagation()
      }
      const newShowKeypad = !showKeypad
      setShowKeypad(newShowKeypad)

      // Show keypad 시에만 포커스 유지
      if (newShowKeypad) {
        setTimeout(() => {
          inputRef.current?.focus()
        }, 0)
      }
    }

    // 키보드 이벤트 처리 수정
    const handleKeyDown = (e) => {
      if (readOnly) return

      // Tab 키는 계산기 숨기고 기본 동작 허용
      if (e.key === 'Tab') {
        setShowKeypad(false)
        return
      }

      // 모든 방향키는 기본 동작 허용
      if (e.key === 'ArrowLeft' || e.key === 'ArrowRight' || e.key === 'ArrowUp' || e.key === 'ArrowDown') {
        setShowKeypad(true)
        return
      }

      // 계산기 허용 키들이 입력되면 키패드 표시 (엔터키 제외)
      if (/^[0-9+\-×÷.=]$/.test(e.key) || e.key === 'Backspace' || e.key === 'Delete' || e.key === '*' || e.key === '/') {
        setShowKeypad(true)
      }

      // 키패드가 숨겨진 상태에서 엔터키는 페이지로 전달
      if (!showKeypad && e.key === 'Enter') {
        return
      }

      e.preventDefault()
      const calculator = calculatorRef.current
      const { allowDecimal } = options

      if (e.key === '.') {
        // allowDecimal이 false이면 소수점 입력 무시
        if (!allowDecimal) return

        // 소수점 입력 처리
        const currentValue = displayValue.toString()
        const parts = currentValue.split(/[+\-×÷]/)
        const lastPart = parts[parts.length - 1]

        // 이미 소수점이 있으면 무시
        if (!lastPart.includes('.')) {
          handleNumber(e.key)
        }
      } else if (/^[0-9]$/.test(e.key)) {
        handleNumber(e.key)
      } else {
        switch (e.key) {
          case '+':
          case '-':
          case '*':
          case '/':
            const opMap = { '*': '×', '/': '÷' }
            handleOperation(opMap[e.key] || e.key)
            break
          case 'Enter':
          case '=':
            if (showKeypad) {
              // 키패드가 보이는 상태에서 엔터키: 계산 후 키패드만 숨김
              handleCompute(true) // 엔터키로 호출됨을 표시
              setShowKeypad(false)
            }
            // 키패드가 숨겨진 상태에서 엔터키: 페이지로 전달 (preventDefault 하지 않음)
            break
          case 'Backspace':
          case 'Delete':
            handleDelete()
            break

          case 'Escape':
            handleClear()
            setShowKeypad(false)
            break

          default:
            break
        }
      }
    }

    return (
      <div ref={containerRef} className="calculator-input-wrapper">
        {label && (
          <label htmlFor={id} className="calculator-label">
            {label}
          </label>
        )}
        <input
          ref={inputRef}
          type="text"
          id={id}
          name={name}
          value={displayValue}
          readOnly={readOnly}
          className={className}
          onClick={() => !readOnly && setShowKeypad(true)}
          onFocus={() => !readOnly && setShowKeypad(true)}
          onChange={handleInputChange}
          onKeyDown={handleKeyDown}
          tabIndex={readOnly ? -1 : 0}
          placeholder={placeholder}
          autoComplete={'off'}
          disabled={disabled}
        />

        {showKeypad && !readOnly && (
          <div className="keypad-container">
            <div className="keypad-grid">
              <button
                onClick={() => {
                  // const newValue = calculatorRef.current.clear()
                  // setDisplayValue(newValue || '0')
                  // onChange(newValue || '0')
                  handleClear()
                  setHasOperation(false)
                }}
                className="btn-clear"
              >
                AC
              </button>
              <button
                onClick={() => {
                  // const newValue = calculatorRef.current.deleteNumber()
                  // setDisplayValue(newValue || '0')
                  // onChange(newValue || '0')
                  //setHasOperation(!!calculatorRef.current.operation)
                  handleDelete()
                }}
                className="btn-delete"
              >
                DEL
              </button>
              <button onClick={() => handleOperation('÷')} className="btn-operator">
                ÷
              </button>

              <button onClick={() => handleOperation('×')} className="btn-operator">
                ×
              </button>
              <button onClick={() => handleOperation('-')} className="btn-operator">
                -
              </button>
              <button onClick={() => handleOperation('+')} className="btn-operator">
                +
              </button>

              {/* 숫자 버튼 */}
              {[1, 2, 3, 4, 5, 6, 7, 8, 9].map((num) => (
                <button key={num} onClick={() => handleNumber(num)} className="btn-number">
                  {num}
                </button>
              ))}
              {/* 0 버튼 */}
              <button onClick={() => handleNumber('0')} className="btn-number btn-zero">
                0
              </button>
              <button
                onClick={() => {
                  const newValue = calculatorRef.current.appendNumber('.')
                  onChange(newValue)
                }}
                className="btn-number"
              >
                .
              </button>
              {/* = 버튼 */}
              <button onClick={() => handleCompute(false)} className="btn-equals">
                =
              </button>
            </div>
          </div>
        )}
      </div>
    )
  },
)

CalculatorInput.displayName = 'CalculatorInput'
