import { useState, useRef } from 'react'
import { decimalToDMS } from '@common/utils/coordinates'
import { ComboBox } from '@common/components/ui/ComboBox'
import { ALL_MODELS } from './OilSpillView'
import type { PredictionModel } from './OilSpillView'
import { analyzeImage } from '../services/predictionApi'
import type { ImageAnalyzeResult } from '../services/predictionApi'

interface PredictionInputSectionProps {
  expanded: boolean
  onToggle: () => void
  accidentTime: string
  onAccidentTimeChange: (time: string) => void
  incidentCoord: { lon: number; lat: number } | null
  onCoordChange: (coord: { lon: number; lat: number }) => void
  isSelectingLocation: boolean
  onMapSelectClick: () => void
  onRunSimulation: () => void
  isRunningSimulation: boolean
  selectedModels: Set<PredictionModel>
  onModelsChange: (models: Set<PredictionModel>) => void
  predictionTime: number
  onPredictionTimeChange: (time: number) => void
  spillType: string
  onSpillTypeChange: (type: string) => void
  oilType: string
  onOilTypeChange: (type: string) => void
  spillAmount: number
  onSpillAmountChange: (amount: number) => void
  incidentName: string
  onIncidentNameChange: (name: string) => void
  spillUnit: string
  onSpillUnitChange: (unit: string) => void
  onImageAnalysisResult?: (result: ImageAnalyzeResult) => void
}

const PredictionInputSection = ({
  expanded,
  onToggle,
  accidentTime,
  onAccidentTimeChange,
  incidentCoord,
  onCoordChange,
  isSelectingLocation,
  onMapSelectClick,
  onRunSimulation,
  isRunningSimulation,
  selectedModels,
  onModelsChange,
  predictionTime,
  onPredictionTimeChange,
  spillType,
  onSpillTypeChange,
  oilType,
  onOilTypeChange,
  spillAmount,
  onSpillAmountChange,
  incidentName,
  onIncidentNameChange,
  spillUnit,
  onSpillUnitChange,
  onImageAnalysisResult,
}: PredictionInputSectionProps) => {
  const [inputMode, setInputMode] = useState<'direct' | 'upload'>('direct')
  const [uploadedFile, setUploadedFile] = useState<File | null>(null)
  const [isAnalyzing, setIsAnalyzing] = useState(false)
  const [analyzeError, setAnalyzeError] = useState<string | null>(null)
  const [analyzeResult, setAnalyzeResult] = useState<ImageAnalyzeResult | null>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0] ?? null
    setUploadedFile(file)
    setAnalyzeError(null)
    setAnalyzeResult(null)
  }

  const handleRemoveFile = () => {
    setUploadedFile(null)
    setAnalyzeError(null)
    setAnalyzeResult(null)
    if (fileInputRef.current) fileInputRef.current.value = ''
  }

  const handleAnalyze = async () => {
    if (!uploadedFile) return
    setIsAnalyzing(true)
    setAnalyzeError(null)
    try {
      const result = await analyzeImage(uploadedFile)
      setAnalyzeResult(result)
      onImageAnalysisResult?.(result)
    } catch (err: unknown) {
      if (err && typeof err === 'object' && 'response' in err) {
        const res = (err as { response?: { data?: { error?: string } } }).response
        if (res?.data?.error === 'GPS_NOT_FOUND') {
          setAnalyzeError('GPS 정보가 없는 이미지입니다')
          return
        }
        if (res?.data?.error === 'TIMEOUT') {
          setAnalyzeError('분석 서버 응답 없음 (시간 초과)')
          return
        }
      }
      setAnalyzeError('이미지 분석 중 오류가 발생했습니다')
    } finally {
      setIsAnalyzing(false)
    }
  }

  return (
    <div className="border-b border-border">
      <div
        onClick={onToggle}
        className="flex items-center justify-between p-4 cursor-pointer hover:bg-[rgba(255,255,255,0.02)]"
      >
        <h3 className="text-[13px] font-bold text-text-2 font-korean">
          예측정보 입력
        </h3>
        <span className="text-[10px] text-text-3">
          {expanded ? '▼' : '▶'}
        </span>
      </div>

      {expanded && (
        <div className="px-4 pb-4 flex flex-col gap-[6px]">
          {/* Input Mode Selection */}
          <div className="flex items-center gap-[10px] text-[11px]">
            <label className="flex items-center gap-[3px] cursor-pointer">
              <input
                type="radio"
                name="prdType"
                checked={inputMode === 'direct'}
                onChange={() => setInputMode('direct')}
                className="accent-[var(--cyan)] m-0 w-[11px] h-[11px]"
              />
              직접 입력
            </label>
            <label className="flex items-center gap-[3px] cursor-pointer">
              <input
                type="radio"
                name="prdType"
                checked={inputMode === 'upload'}
                onChange={() => setInputMode('upload')}
                className="accent-[var(--cyan)] m-0 w-[11px] h-[11px]"
              />
              이미지 업로드
            </label>
          </div>

          {/* Direct Input Mode */}
          {inputMode === 'direct' && (
            <>
              <input
                className="prd-i"
                placeholder="사고명 직접 입력"
                value={incidentName}
                onChange={(e) => onIncidentNameChange(e.target.value)}
              />
              <input className="prd-i" placeholder="또는 사고 리스트에서 선택" readOnly />
            </>
          )}

          {/* Image Upload Mode */}
          {inputMode === 'upload' && (
            <>
              {/* 파일 선택 영역 */}
              {!uploadedFile ? (
                <label
                  className="flex items-center justify-center text-[11px] text-text-3 cursor-pointer"
                  style={{
                    padding: '20px',
                    background: 'var(--bg0)',
                    border: '2px dashed var(--bd)',
                    borderRadius: 'var(--rS)',
                    transition: '0.15s',
                  }}
                  onMouseEnter={(e) => {
                    e.currentTarget.style.borderColor = 'var(--cyan)'
                    e.currentTarget.style.background = 'rgba(6,182,212,0.05)'
                  }}
                  onMouseLeave={(e) => {
                    e.currentTarget.style.borderColor = 'var(--bd)'
                    e.currentTarget.style.background = 'var(--bg0)'
                  }}
                >
                  📁 이미지 파일을 선택하세요
                  <input
                    ref={fileInputRef}
                    type="file"
                    accept="image/*"
                    onChange={handleFileSelect}
                    className="hidden"
                  />
                </label>
              ) : (
                <div
                  className="flex items-center justify-between font-mono text-[10px] bg-bg-0 border border-border"
                  style={{ padding: '8px 10px', borderRadius: 'var(--rS)' }}
                >
                  <span className="text-text-2">📄 {uploadedFile.name}</span>
                  <button
                    onClick={handleRemoveFile}
                    className="text-[10px] text-text-3 bg-transparent border-none cursor-pointer"
                    style={{ padding: '2px 6px', transition: '0.15s' }}
                    onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--red)' }}
                    onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--t3)' }}
                  >
                    ✕
                  </button>
                </div>
              )}

              {/* 분석 실행 버튼 */}
              <button
                className="prd-btn pri"
                style={{ padding: '7px', fontSize: '11px' }}
                onClick={handleAnalyze}
                disabled={!uploadedFile || isAnalyzing}
              >
                {isAnalyzing ? '⏳ 분석 중...' : '🔍 이미지 분석 실행'}
              </button>

              {/* 에러 메시지 */}
              {analyzeError && (
                <div
                  className="text-[10px] font-semibold"
                  style={{
                    padding: '6px 8px',
                    background: 'rgba(239,68,68,0.1)',
                    border: '1px solid rgba(239,68,68,0.3)',
                    borderRadius: 'var(--rS)',
                    color: 'var(--red)',
                  }}
                >
                  ⚠ {analyzeError}
                </div>
              )}

              {/* 분석 완료 메시지 */}
              {analyzeResult && (
                <div
                  className="text-[10px] font-semibold"
                  style={{
                    padding: '6px 8px',
                    background: 'rgba(34,197,94,0.1)',
                    border: '1px solid rgba(34,197,94,0.3)',
                    borderRadius: 'var(--rS)',
                    color: '#22c55e',
                    lineHeight: 1.6,
                  }}
                >
                  ✓ 분석 완료<br />
                  <span className="font-normal text-text-3">
                    위도 {analyzeResult.lat.toFixed(4)} / 경도 {analyzeResult.lon.toFixed(4)}<br />
                    유종: {analyzeResult.oilType} / 면적: {analyzeResult.area.toFixed(1)} m²
                  </span>
                </div>
              )}
            </>
          )}

          {/* 사고 발생 시각 */}
          <div className="flex flex-col gap-0.5">
            <label className="text-[9px] text-text-3 font-korean">사고 발생 시각 (KST)</label>
            <input
              className="prd-i"
              type="datetime-local"
              value={accidentTime}
              onChange={(e) => onAccidentTimeChange(e.target.value)}
              style={{ colorScheme: 'dark' }}
            />
          </div>

          {/* Coordinates + Map Button */}
          <div className="flex flex-col gap-1">
            <div className="grid items-center gap-1" style={{ gridTemplateColumns: '1fr 1fr auto' }}>
              <input
                className="prd-i"
                type="number"
                step="0.0001"
                value={incidentCoord?.lat ?? ''}
                onChange={(e) => {
                  const value = e.target.value === '' ? 0 : parseFloat(e.target.value)
                  onCoordChange({ lon: incidentCoord?.lon ?? 0, lat: isNaN(value) ? 0 : value })
                }}
                placeholder="위도°"
              />
              <input
                className="prd-i"
                type="number"
                step="0.0001"
                value={incidentCoord?.lon ?? ''}
                onChange={(e) => {
                  const value = e.target.value === '' ? 0 : parseFloat(e.target.value)
                  onCoordChange({ lat: incidentCoord?.lat ?? 0, lon: isNaN(value) ? 0 : value })
                }}
                placeholder="경도°"
              />
              <button
                className={`prd-map-btn${isSelectingLocation ? ' active' : ''}`}
                onClick={onMapSelectClick}
              >📍 지도</button>
            </div>
            {/* 도분초 표시 */}
            {incidentCoord && !isNaN(incidentCoord.lat) && !isNaN(incidentCoord.lon) && (
              <div
                className="text-[9px] text-text-3 font-mono border border-border bg-bg-0"
                style={{ padding: '4px 8px', borderRadius: 'var(--rS)' }}
              >
                {decimalToDMS(incidentCoord.lat, true)} / {decimalToDMS(incidentCoord.lon, false)}
              </div>
            )}
          </div>

          {/* Oil Type + Oil Kind */}
          <div className="grid grid-cols-2 gap-1">
            <ComboBox
              className="prd-i"
              value={spillType}
              onChange={onSpillTypeChange}
              options={[
                { value: '연속', label: '연속' },
                { value: '비연속', label: '비연속' },
                { value: '순간 유출', label: '순간 유출' }
              ]}
            />
            <ComboBox
              className="prd-i"
              value={oilType}
              onChange={onOilTypeChange}
              options={[
                { value: '벙커C유', label: '벙커C유' },
                { value: '경유', label: '경유' },
                { value: '원유', label: '원유' },
                { value: '중유', label: '중유' },
                { value: '등유', label: '등유' },
                { value: '휘발유', label: '휘발유' }
              ]}
            />
          </div>

          {/* Volume + Unit + Duration */}
          <div className="grid items-center gap-1" style={{ gridTemplateColumns: '1fr 65px 1fr' }}>
            <input
              className="prd-i"
              placeholder="유출량"
              type="number"
              min="1"
              step="1"
              value={spillAmount}
              onChange={(e) => onSpillAmountChange(parseInt(e.target.value) || 0)}
            />
            <ComboBox
              className="prd-i"
              value={spillUnit}
              onChange={onSpillUnitChange}
              options={[
                { value: 'kL', label: 'kL' },
                { value: 'ton', label: 'Ton' },
                { value: 'barrel', label: '배럴' }
              ]}
            />
            <ComboBox
              className="prd-i"
              value={predictionTime}
              onChange={(v) => onPredictionTimeChange(parseInt(v))}
              options={[
                { value: '6', label: '6시간' },
                { value: '12', label: '12시간' },
                { value: '24', label: '24시간' },
                { value: '48', label: '48시간' },
                { value: '72', label: '72시간' }
              ]}
            />
          </div>

          {/* Divider */}
          <div className="h-px bg-border my-0.5" />

          {/* Model Selection (다중 선택) */}
          <div className="flex flex-wrap gap-[3px]">
            {([
              { id: 'KOSPS' as PredictionModel, color: 'var(--cyan)' },
              { id: 'POSEIDON' as PredictionModel, color: 'var(--red)' },
              { id: 'OpenDrift' as PredictionModel, color: 'var(--blue)' },
            ] as const).map(m => (
              <div
                key={m.id}
                className={`prd-mc ${selectedModels.has(m.id) ? 'on' : ''} cursor-pointer`}
                onClick={() => {
                  const next = new Set(selectedModels)
                  if (next.has(m.id)) {
                    next.delete(m.id)
                  } else {
                    next.add(m.id)
                  }
                  onModelsChange(next)
                }}
              >
                <span className="prd-md" style={{ background: m.color }} />
                {m.id}
              </div>
            ))}
            <div
              className={`prd-mc ${selectedModels.size === ALL_MODELS.length ? 'on' : ''} cursor-pointer`}
              onClick={() => {
                if (selectedModels.size === ALL_MODELS.length) {
                  onModelsChange(new Set(['KOSPS']))
                } else {
                  onModelsChange(new Set(ALL_MODELS))
                }
              }}
            >
              <span className="prd-md" style={{ background: 'var(--purple)' }} />
              앙상블
            </div>
          </div>

          {/* Run Button */}
          <button
            className="prd-btn pri mt-0.5"
            style={{ padding: '7px', fontSize: '11px' }}
            onClick={onRunSimulation}
            disabled={isRunningSimulation}
          >
            {isRunningSimulation ? '⏳ 실행 중...' : '🔬 확산예측 실행'}
          </button>
        </div>
      )}
    </div>
  )
}

export default PredictionInputSection
