import { useState, useRef, useEffect } from 'react';
import type { PredictionModel } from './OilSpillView';

interface RecalcModalProps {
  isOpen: boolean;
  onClose: () => void;
  incidentName: string;
  oilType: string;
  spillAmount: number;
  spillType: string;
  predictionTime: number;
  incidentCoord: { lat: number; lon: number };
  selectedModels: Set<PredictionModel>;
  onSubmit: (params: {
    oilType: string;
    spillAmount: number;
    spillType: string;
    predictionTime: number;
    incidentCoord: { lat: number; lon: number };
    selectedModels: Set<PredictionModel>;
  }) => void;
}

type RecalcPhase = 'editing' | 'running' | 'done';

const OIL_TYPES = [
  '벙커C유',
  '원유(중질)',
  '원유(경질)',
  '디젤유(경유)',
  '휘발유',
  '등유',
  '윤활유',
  'HFO 380',
  'HFO 180',
];
const SPILL_TYPES = ['연속', '순간', '점진적'];
const PREDICTION_TIMES = [6, 12, 24, 48, 72, 96, 120];
const snapToValidTime = (t: number): number =>
  PREDICTION_TIMES.includes(t) ? t : (PREDICTION_TIMES.find((h) => h >= t) ?? PREDICTION_TIMES[0]);

export function RecalcModal({
  isOpen,
  onClose,
  incidentName,
  oilType: initOilType,
  spillAmount: initSpillAmount,
  spillType: initSpillType,
  predictionTime: initPredictionTime,
  incidentCoord: initCoord,
  selectedModels: initModels,
  onSubmit,
}: RecalcModalProps) {
  const backdropRef = useRef<HTMLDivElement>(null);

  const [oilType, setOilType] = useState(initOilType);
  const [spillAmount, setSpillAmount] = useState(initSpillAmount);
  const [spillUnit, setSpillUnit] = useState<'kl' | 'ton' | 'bbl'>('kl');
  const [spillType, setSpillType] = useState(initSpillType);
  const [predictionTime, setPredictionTime] = useState(() => snapToValidTime(initPredictionTime));
  const [lat, setLat] = useState(initCoord.lat);
  const [lon, setLon] = useState(initCoord.lon);
  const [models, setModels] = useState<Set<PredictionModel>>(new Set(initModels));
  const [phase, setPhase] = useState<RecalcPhase>('editing');

  // Sync when modal opens
  /* eslint-disable react-hooks/set-state-in-effect */
  useEffect(() => {
    if (isOpen) {
      setOilType(initOilType);
      setSpillAmount(initSpillAmount);
      setSpillType(initSpillType);
      setPredictionTime(snapToValidTime(initPredictionTime));
      setLat(initCoord.lat);
      setLon(initCoord.lon);
      setModels(new Set(initModels));
      setPhase('editing');
    }
  }, [
    isOpen,
    initOilType,
    initSpillAmount,
    initSpillType,
    initPredictionTime,
    initCoord.lat,
    initCoord.lon,
    initModels,
  ]);
  /* eslint-enable react-hooks/set-state-in-effect */

  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (e.target === backdropRef.current) onClose();
    };
    if (isOpen) document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [isOpen, onClose]);

  const toggleModel = (model: PredictionModel) => {
    setModels((prev) => {
      const next = new Set(prev);
      if (next.has(model)) next.delete(model);
      else next.add(model);
      return next;
    });
  };

  const handleRun = () => {
    setPhase('running');
    setTimeout(() => {
      setPhase('done');
      setTimeout(() => {
        onSubmit({
          oilType,
          spillAmount,
          spillType,
          predictionTime,
          incidentCoord: { lat, lon },
          selectedModels: models,
        });
        onClose();
      }, 1000);
    }, 2500);
  };

  if (!isOpen) return null;

  return (
    <div
      ref={backdropRef}
      style={{
        inset: 0,
        background: 'rgba(0,0,0,0.55)',
        backdropFilter: 'blur(4px)',
      }}
      className="fixed z-[9999] flex items-center justify-center"
    >
      <div
        style={{
          width: '380px',
          maxHeight: 'calc(100vh - 120px)',
          background: 'var(--bg-surface)',
          borderRadius: '14px',
          boxShadow: '0 20px 60px rgba(0,0,0,0.5)',
        }}
        className="border border-stroke overflow-hidden flex flex-col"
      >
        {/* Header */}
        <div
          style={{
            padding: '16px 20px',
          }}
          className="border-b border-stroke flex items-center gap-3"
        >
          <div
            style={{
              width: '36px',
              height: '36px',
              borderRadius: '10px',
              background: 'linear-gradient(135deg, rgba(249,115,22,0.2), rgba(6,182,212,0.2))',
              border: '1px solid rgba(249,115,22,0.3)',
              fontSize: 'var(--font-size-body-1)',
            }}
            className="flex items-center justify-center"
          >
            🔄
          </div>
          <div className="flex-1">
            <h2 className="text-subtitle font-bold m-0">확산예측 재계산</h2>
            <div className="text-caption text-fg-default mt-[2px]">
              유출유·유출량 등 파라미터를 수정하여 재실행
            </div>
          </div>
          <button
            onClick={onClose}
            style={{
              width: '28px',
              height: '28px',
              borderRadius: '6px',
              background: 'var(--bg-card)',
              fontSize: 'var(--font-size-caption)',
            }}
            className="border border-stroke text-fg-default cursor-pointer flex items-center justify-center"
          >
            ✕
          </button>
        </div>

        {/* Scrollable Content */}
        <div
          style={{
            padding: '16px 20px',
          }}
          className="flex-1 overflow-y-auto flex flex-col gap-[14px]"
        >
          {/* 현재 분석 정보 */}
          <div
            style={{
              padding: '10px 12px',
              background: 'rgba(6,182,212,0.04)',
              border: '1px solid rgba(6,182,212,0.15)',
              borderRadius: '8px',
            }}
          >
            <div className="text-caption font-bold text-color-accent mb-1.5">현재 분석 정보</div>
            <div
              style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '4px' }}
              className="text-caption"
            >
              <InfoItem label="사고명" value={incidentName} />
              <InfoItem label="유종" value={initOilType} />
              <InfoItem label="유출량" value={`${initSpillAmount} kl`} />
              <InfoItem label="예측시간" value={`${initPredictionTime}시간`} />
            </div>
          </div>

          {/* 유종 */}
          <FieldGroup label="유종">
            <select className="prd-i" value={oilType} onChange={(e) => setOilType(e.target.value)}>
              {OIL_TYPES.map((t) => (
                <option key={t} value={t}>
                  {t}
                </option>
              ))}
            </select>
          </FieldGroup>

          {/* 유출량 */}
          <FieldGroup label="유출량">
            <div className="flex gap-1.5">
              <input
                type="number"
                className="prd-i flex-1"
                value={spillAmount}
                onChange={(e) => setSpillAmount(Number(e.target.value))}
              />
              <select
                className="prd-i"
                value={spillUnit}
                onChange={(e) => setSpillUnit(e.target.value as 'kl' | 'ton' | 'bbl')}
                style={{ width: '70px' }}
              >
                <option value="kl">kl</option>
                <option value="ton">ton</option>
                <option value="bbl">bbl</option>
              </select>
            </div>
          </FieldGroup>

          {/* 유출 형태 */}
          <FieldGroup label="유출 형태">
            <select
              className="prd-i"
              value={spillType}
              onChange={(e) => setSpillType(e.target.value)}
            >
              {SPILL_TYPES.map((t) => (
                <option key={t} value={t}>
                  {t}
                </option>
              ))}
            </select>
          </FieldGroup>

          {/* 예측 시간 */}
          <FieldGroup label="예측 시간">
            <select
              className="prd-i"
              value={predictionTime}
              onChange={(e) => setPredictionTime(Number(e.target.value))}
            >
              {PREDICTION_TIMES.map((h) => (
                <option key={h} value={h}>
                  {h}시간
                </option>
              ))}
            </select>
          </FieldGroup>

          {/* 유출 위치 */}
          <FieldGroup label="유출 위치 (좌표)">
            <div className="flex gap-1.5">
              <div className="flex-1">
                <div className="text-caption text-fg-default mb-[3px]">위도 (N)</div>
                <input
                  type="number"
                  className="prd-i font-mono"
                  value={lat}
                  step={0.0001}
                  onChange={(e) => setLat(Number(e.target.value))}
                />
              </div>
              <div className="flex-1">
                <div className="text-caption text-fg-default mb-[3px]">경도 (E)</div>
                <input
                  type="number"
                  className="prd-i font-mono"
                  value={lon}
                  step={0.0001}
                  onChange={(e) => setLon(Number(e.target.value))}
                />
              </div>
            </div>
          </FieldGroup>

          {/* 모델 선택 */}
          <FieldGroup label="예측 모델 선택">
            <div className="flex flex-wrap gap-1.5">
              {[
                { model: 'KOSPS' as PredictionModel, color: 'var(--color-accent)', ready: false },
                { model: 'POSEIDON' as PredictionModel, color: 'var(--color-danger)', ready: true },
                { model: 'OpenDrift' as PredictionModel, color: 'var(--color-info)', ready: true },
              ].map(({ model, color, ready }) => (
                <button
                  key={model}
                  className={`prd-mc ${models.has(model) ? 'on' : ''}`}
                  onClick={() => {
                    if (!ready) {
                      alert(`${model} 모델은 현재 준비중입니다.`);
                      return;
                    }
                    toggleModel(model);
                  }}
                  style={{ fontSize: 'var(--font-size-caption)', padding: '5px 10px' }}
                >
                  <span className="prd-md" style={{ background: color }} />
                  {model}
                </button>
              ))}
            </div>
          </FieldGroup>
        </div>

        {/* Footer */}
        <div
          style={{
            padding: '14px 20px',
          }}
          className="border-t border-stroke flex gap-2"
        >
          <button
            onClick={onClose}
            disabled={phase !== 'editing'}
            style={{
              padding: '10px',
              borderRadius: '8px',
              background: 'var(--bg-card)',
              opacity: phase !== 'editing' ? 0.5 : 1,
            }}
            className="flex-1 text-label-1 font-semibold border border-stroke text-fg-sub cursor-pointer"
          >
            취소
          </button>
          <button
            onClick={handleRun}
            disabled={phase !== 'editing' || models.size === 0}
            style={{
              padding: '10px',
              borderRadius: '8px',
              cursor: phase === 'editing' ? 'pointer' : 'wait',
              background:
                phase === 'done'
                  ? 'rgba(34,197,94,0.15)'
                  : phase === 'running'
                    ? 'var(--bg-card)'
                    : 'linear-gradient(135deg, var(--color-warning), var(--color-accent))',
              border:
                phase === 'done'
                  ? '1px solid rgba(34,197,94,0.4)'
                  : phase === 'running'
                    ? '1px solid var(--stroke-default)'
                    : 'none',
              color:
                phase === 'done'
                  ? 'var(--color-success)'
                  : phase === 'running'
                    ? 'var(--color-warning)'
                    : '#fff',
              opacity: models.size === 0 && phase === 'editing' ? 0.5 : 1,
            }}
            className="flex-[2] text-label-1 font-bold"
          >
            {phase === 'done'
              ? '✅ 재계산 완료!'
              : phase === 'running'
                ? '⏳ 재계산 실행중...'
                : '🔄 재계산 실행'}
          </button>
        </div>
      </div>
    </div>
  );
}

function FieldGroup({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div>
      <div className="text-caption font-bold text-fg-sub mb-1.5">{label}</div>
      {children}
    </div>
  );
}

function InfoItem({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex justify-between py-[2px]">
      <span className="text-fg-default">{label}</span>
      <span className="font-semibold font-mono">{value}</span>
    </div>
  );
}
