import { useState, useEffect, useCallback } from 'react';
import { saveReport } from '../services/reportsApi';
import type {
  OilSpillReportData,
} from '@interfaces/reports/ReportsInterface';
import type {
  Jurisdiction,
} from '@/types/reports/ReportsType';
import { Page1 } from './contents/Page1';
import { Page2 } from './contents/Page2';
import { Page3 } from './contents/Page3';
import { Page4 } from './contents/Page4';
import { Page5 } from './contents/Page5';
import { Page6 } from './contents/Page6';
import { Page7 } from './contents/Page7';
/* eslint-disable react-refresh/only-export-components */

// eslint-disable-next-line react-refresh/only-export-components
export function createEmptyReport(jurisdiction?: Jurisdiction): OilSpillReportData {
  const now = new Date();
  const ts = `${now.getFullYear()}.${String(now.getMonth() + 1).padStart(2, '0')}.${String(now.getDate()).padStart(2, '0')}  ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
  return {
    id: `RPT-${Date.now()}`,
    title: '',
    createdAt: now.toISOString(),
    updatedAt: now.toISOString(),
    author: '',
    reportType: '예측보고서',
    analysisCategory: '',
    jurisdiction: jurisdiction ?? '남해청',
    status: '수행중',
    incident: {
      name: '',
      writeTime: ts,
      shipName: '',
      agent: '',
      location: '',
      lat: '',
      lon: '',
      occurTime: '',
      accidentType: '',
      pollutant: '',
      spillAmount: '',
      depth: '',
      seabed: '',
    },
    tide: [{ date: '', tideType: '', lowTide1: '', highTide1: '', lowTide2: '', highTide2: '' }],
    weather: [
      {
        time: '',
        sunrise: '',
        sunset: '',
        windDir: '',
        windSpeed: '',
        currentDir: '',
        currentSpeed: '',
        waveHeight: '',
      },
    ],
    spread: [
      { elapsed: '3시간', weathered: '', seaRemain: '', coastAttach: '', area: '' },
      { elapsed: '6시간', weathered: '', seaRemain: '', coastAttach: '', area: '' },
    ],
    analysis: '',
    aquaculture: [{ type: '', area: '', distance: '' }],
    beaches: [{ name: '', distance: '' }],
    markets: [{ name: '', distance: '' }],
    esi: [
      { code: 'ESI 1', type: '수직암반', length: '' },
      { code: 'ESI 2', type: '수평암반', length: '' },
      { code: 'ESI 3', type: '세립질 모래', length: '' },
      { code: 'ESI 4', type: '조립질 모래', length: '' },
      { code: 'ESI 5', type: '모래·자갈', length: '' },
      { code: 'ESI 6A', type: '자갈', length: '' },
      { code: 'ESI 6B', type: '투과성 사석', length: '' },
      { code: 'ESI 7', type: '반폐쇄성 해안', length: '' },
      { code: 'ESI 8A', type: '갯벌', length: '' },
      { code: 'ESI 8B', type: '염습지', length: '' },
    ],
    species: [
      { category: '양서파충류', species: '' },
      { category: '조류', species: '' },
      { category: '포유류', species: '' },
    ],
    habitat: [{ type: '갯벌', area: '' }],
    sensitivity: [
      { level: '매우 높음', area: '', color: '#ef4444' },
      { level: '높음', area: '', color: '#f97316' },
      { level: '보통', area: '', color: '#eab308' },
      { level: '낮음', area: '', color: '#22c55e' },
    ],
    vessels: [
      {
        name: '',
        org: '',
        dist: '',
        speed: '',
        ton: '',
        collectorType: '',
        collectorCap: '',
        boomType: '',
        boomLength: '',
      },
    ],
    etcEquipment: '',
    recovery: [{ shipName: '', period: '' }],
    result: {
      spillTotal: '',
      weatheredTotal: '',
      recoveredTotal: '',
      seaRemainTotal: '',
      coastAttachTotal: '',
    },
  };
}

// eslint-disable-next-line react-refresh/only-export-components
export function createSampleReport(): OilSpillReportData {
  return {
    id: `RPT-${Date.now()}`,
    title: '여수 수변공원 Diesel 유출사고 대응지원',
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    author: '남해청_방제과',
    reportType: '초기보고서',
    analysisCategory: '유출유 확산예측',
    jurisdiction: '남해청',
    status: '완료',
    incident: {
      name: '여수 수변공원 유출사고',
      writeTime: '2025.07.16  13:48',
      shipName: '수변공원',
      agent: '',
      location: '여수 돌산 남방',
      lat: '34° 43′ 37.6″',
      lon: '127° 43′ 32.6″',
      occurTime: '2025. 07. 08. 17:55',
      accidentType: '시설 파손',
      pollutant: 'Diesel',
      spillAmount: '1㎘',
      depth: '12m',
      seabed: '모래',
    },
    tide: [
      {
        date: '2025-07-08 20:55',
        tideType: '배꼽사리',
        lowTide1: '01:53 (146)',
        highTide1: '13:19 (104)',
        lowTide2: '07:17 (253)',
        highTide2: '20:24 (310)',
      },
      {
        date: '2025-07-08 23:55',
        tideType: '배꼽사리',
        lowTide1: '01:53 (146)',
        highTide1: '13:19 (104)',
        lowTide2: '07:17 (253)',
        highTide2: '20:24 (310)',
      },
    ],
    weather: [
      {
        time: '2025-07-08 20:55',
        sunrise: '05:22',
        sunset: '19:46',
        windDir: '북동',
        windSpeed: '0.0',
        currentDir: '북',
        currentSpeed: '0.0 / 0.0',
        waveHeight: '0.0',
      },
      {
        time: '2025-07-08 23:55',
        sunrise: '05:22',
        sunset: '19:46',
        windDir: '북동',
        windSpeed: '0.0',
        currentDir: '북',
        currentSpeed: '0.0 / 0.0',
        waveHeight: '0.0',
      },
    ],
    spread: [
      { elapsed: '3시간', weathered: '0.48', seaRemain: '0.52', coastAttach: '0.12', area: '1.75' },
      { elapsed: '6시간', weathered: '0.64', seaRemain: '0.36', coastAttach: '0.24', area: '3.49' },
    ],
    analysis: '',
    aquaculture: [
      { type: '', area: '3.19', distance: '0.56' },
      { type: '', area: '20.15', distance: '0.83' },
      { type: '어류', area: '3.84', distance: '1.14' },
      { type: '', area: '2.89', distance: '1.40' },
      { type: '어류', area: '0.90', distance: '1.42' },
    ],
    beaches: [
      { name: '검은모래해수욕장', distance: '5.86' },
      { name: '무슬목해수욕장', distance: '6.69' },
      { name: '모사금해수욕장', distance: '8.18' },
    ],
    markets: [{ name: '돌산대교 회타운', distance: '1.09' }],
    esi: [
      { code: 'ESI 1', type: '수직암반', length: '29.05 km' },
      { code: 'ESI 2', type: '수평암반', length: '13.76 km' },
      { code: 'ESI 3', type: '세립질 모래', length: '1.03 km' },
      { code: 'ESI 4', type: '조립질 모래', length: '0.47 km' },
      { code: 'ESI 5', type: '모래·자갈', length: '21.10 km' },
      { code: 'ESI 6A', type: '자갈', length: '15.29 km' },
      { code: 'ESI 6B', type: '투과성 사석', length: '26.60 km' },
      { code: 'ESI 7', type: '반폐쇄성 해안', length: '9.39 km' },
      { code: 'ESI 8A', type: '갯벌', length: '0.00 km' },
      { code: 'ESI 8B', type: '염습지', length: '3.43 km' },
    ],
    species: [
      { category: '양서파충류', species: '' },
      { category: '조류', species: '뿔논병아리(겨울철새), 꾀꼬리(여름철새)' },
      { category: '포유류', species: '수달' },
    ],
    habitat: [{ type: '갯벌', area: '4.32 km²' }],
    sensitivity: [
      { level: '매우 높음', area: '18.54', color: '#ef4444' },
      { level: '높음', area: '31.32', color: '#f97316' },
      { level: '보통', area: '59.22', color: '#eab308' },
      { level: '낮음', area: '32.13', color: '#22c55e' },
    ],
    vessels: [
      {
        name: '방제15호',
        org: '서해청',
        dist: '0.41',
        speed: '7.0',
        ton: '450.0',
        collectorType: '흡착',
        collectorCap: '140.0',
        boomType: 'B',
        boomLength: '60',
      },
      {
        name: '방제26호',
        org: '서해청',
        dist: '0.41',
        speed: '13.0',
        ton: '360.0',
        collectorType: '흡착',
        collectorCap: '100.0',
        boomType: 'B',
        boomLength: '300',
      },
      {
        name: '방제1001호',
        org: '서해청',
        dist: '0.74',
        speed: '10.0',
        ton: '564.0',
        collectorType: '흡착',
        collectorCap: '30.0',
        boomType: 'B',
        boomLength: '20',
      },
      {
        name: '전남939호',
        org: '서해청',
        dist: '0.74',
        speed: '10.0',
        ton: '149.0',
        collectorType: '흡착',
        collectorCap: '30.0',
        boomType: 'B',
        boomLength: '300',
      },
      {
        name: '동양방제호',
        org: '서해청',
        dist: '1.78',
        speed: '10.0',
        ton: '179.0',
        collectorType: '위어,흡착',
        collectorCap: '66.0',
        boomType: 'C',
        boomLength: '300',
      },
      {
        name: '화학방제2함',
        org: '서해청',
        dist: '3.00',
        speed: '13.0',
        ton: '501.0',
        collectorType: '위어,브러쉬',
        collectorCap: '150.0',
        boomType: '특수',
        boomLength: '60',
      },
      {
        name: '우진방제호',
        org: '서해청',
        dist: '13.22',
        speed: '9.0',
        ton: '79.0',
        collectorType: '위어',
        collectorCap: '20.0',
        boomType: 'C',
        boomLength: '300',
      },
    ],
    etcEquipment: '',
    recovery: [{ shipName: '방제15호', period: '0' }],
    result: {
      spillTotal: '1',
      weatheredTotal: '0.64',
      recoveredTotal: '0',
      seaRemainTotal: '0.36',
      coastAttachTotal: '0.24',
    },
  };
}

// ─── localStorage helpers 제거됨 — reportsApi.ts 사용 ────────

// ─── Styles ─────────────────────────────────────────────────
export const S = {
  page: {
    background: 'var(--bg-surface)',
    padding: '32px 40px',
    marginBottom: '24px',
    borderRadius: '6px',
    border: '1px solid var(--stroke-default)',
    fontFamily: 'var(--font-korean)',
    fontSize: 'var(--font-size-label-1)',
    lineHeight: '1.6',
    position: 'relative' as const,
    width: '100%',
    boxSizing: 'border-box' as const,
  },
  sectionTitle: {
    background: 'rgba(6,182,212,0.12)',
    color: 'var(--color-accent)',
    padding: '8px 16px',
    fontSize: 'var(--font-size-title-4)',
    fontWeight: 700,
    marginBottom: '12px',
    borderRadius: '4px',
    border: '1px solid rgba(6,182,212,0.2)',
  },
  subHeader: {
    fontSize: 'var(--font-size-title-3)',
    fontWeight: 700,
    color: 'var(--color-accent)',
    marginBottom: '12px',
    borderBottom: '2px solid var(--stroke-default)',
    paddingBottom: '6px',
  },
  table: {
    width: '100%',
    tableLayout: 'fixed' as const,
    borderCollapse: 'collapse' as const,
    fontSize: 'var(--font-size-caption)',
    marginBottom: '16px',
  },
  th: {
    background: 'var(--bg-card)',
    border: '1px solid var(--stroke-default)',
    padding: '6px 10px',
    fontWeight: 600,
    color: 'var(--fg-sub)',
    textAlign: 'center' as const,
    fontSize: 'var(--font-size-caption)',
  },
  td: {
    border: '1px solid var(--stroke-default)',
    padding: '5px 10px',
    textAlign: 'center' as const,
    fontSize: 'var(--font-size-caption)',
    color: 'var(--fg-sub)',
  },
  tdLeft: {
    border: '1px solid var(--stroke-default)',
    padding: '5px 10px',
    textAlign: 'left' as const,
    fontSize: 'var(--font-size-caption)',
    color: 'var(--fg-sub)',
  },
  thLabel: {
    background: 'var(--bg-card)',
    border: '1px solid var(--stroke-default)',
    padding: '6px 10px',
    fontWeight: 600,
    color: 'var(--fg-sub)',
    textAlign: 'left' as const,
    fontSize: 'var(--font-size-caption)',
    width: '120px',
  },
  mapPlaceholder: {
    width: '100%',
    height: '240px',
    background: 'var(--bg-base)',
    border: '2px dashed var(--stroke-default)',
    borderRadius: '4px',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    color: 'var(--fg-disabled)',
    fontSize: 'var(--font-size-title-4)',
    fontWeight: 600,
    marginBottom: '16px',
  },
};

// ─── Editable cell ──────────────────────────────────────────
export const inputStyle: React.CSSProperties = {
  width: '100%',
  background: 'var(--bg-base)',
  border: '1px solid var(--stroke-light)',
  borderRadius: '3px',
  padding: '4px 8px',
  fontSize: 'var(--font-size-caption)',
  outline: 'none',
  textAlign: 'center',
};

// ─── Helpers (shared with contents/) ───────────────────────
export const getSeasonKey = (occurTime: string): 'SP_G' | 'SM_G' | 'FA_G' | 'WT_G' => {
  const m = occurTime.match(/\d{4}[.\-\s]+(\d{1,2})[.\-\s]/);
  const month = m ? parseInt(m[1]) : 0;
  if (month >= 3 && month <= 5) return 'SP_G';
  if (month >= 6 && month <= 8) return 'SM_G';
  if (month >= 9 && month <= 11) return 'FA_G';
  return 'WT_G';
};

export const parseCoord = (s: string): number | null => {
  const d = parseFloat(s);
  if (!isNaN(d)) return d;
  const m = s.match(/(\d+)[°]\s*(\d+)[′']\s*([\d.]+)[″"]/);
  if (m) return Number(m[1]) + Number(m[2]) / 60 + Number(m[3]) / 3600;
  return null;
};

export const haversineKm = (lat1: number, lon1: number, lat2: number, lon2: number): number => {
  const R = 6371;
  const dLat = ((lat2 - lat1) * Math.PI) / 180;
  const dLon = ((lon2 - lon1) * Math.PI) / 180;
  const a =
    Math.sin(dLat / 2) ** 2 +
    Math.cos((lat1 * Math.PI) / 180) * Math.cos((lat2 * Math.PI) / 180) * Math.sin(dLon / 2) ** 2;
  return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
};

export const getGeomCentroid = (geom: { type: string; coordinates: unknown }): [number, number] | null => {
  if (geom.type === 'Point') return geom.coordinates as [number, number];
  if (geom.type === 'Polygon') {
    const pts = (geom.coordinates as [number, number][][])[0];
    const avg = pts.reduce((a, c) => [a[0] + c[0], a[1] + c[1]], [0, 0]);
    return [avg[0] / pts.length, avg[1] / pts.length];
  }
  if (geom.type === 'MultiPolygon') {
    const all = (geom.coordinates as [number, number][][][]).flatMap((p) => p[0]);
    const avg = all.reduce((a, c) => [a[0] + c[0], a[1] + c[1]], [0, 0]);
    return [avg[0] / all.length, avg[1] / all.length];
  }
  return null;
};

export const CATEGORY_COLORS = [
  { keywords: ['어장', '양식'], color: '#f97316', label: '어장/양식장' },
  { keywords: ['해수욕'], color: '#3b82f6', label: '해수욕장' },
  { keywords: ['수산시장', '어시장'], color: '#a855f7', label: '수산시장' },
  { keywords: ['갯벌'], color: '#92400e', label: '갯벌' },
  { keywords: ['서식지'], color: '#16a34a', label: '서식지' },
  {
    keywords: ['보호종', '생물', '조류', '포유', '파충', '양서'],
    color: '#ec4899',
    label: '보호종/생물종',
  },
] as const;

export const getCategoryColor = (category: string): string => {
  for (const { keywords, color } of CATEGORY_COLORS) {
    if ((keywords as readonly string[]).some((kw) => category.includes(kw))) return color;
  }
  return '#06b6d4';
};

export const SENS_LEVELS = [
  { key: 5, level: '매우 높음', color: '#ef4444' },
  { key: 4, level: '높음', color: '#f97316' },
  { key: 3, level: '보통', color: '#eab308' },
  { key: 2, level: '낮음', color: '#22c55e' },
];


// ─── Main Template Component ────────────────────────────────
interface Props {
  mode: 'preview' | 'edit' | 'view';
  initialData?: OilSpillReportData;
  onSave?: (data: OilSpillReportData) => void;
  onBack?: () => void;
}

export function OilSpillReportTemplate({ mode, initialData, onSave, onBack }: Props) {
  const [data, setData] = useState<OilSpillReportData>(() => initialData || createSampleReport());
  const [currentPage, setCurrentPage] = useState(0);
  const [viewMode, setViewMode] = useState<'page' | 'all'>('all');
  const editing = mode === 'edit';

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    if (initialData) setData(initialData);
  }, [initialData]);

  const handleSave = useCallback(async () => {
    let reportData = data;
    if (!data.title) {
      const title = data.incident.name || `보고서 ${new Date().toLocaleDateString('ko-KR')}`;
      reportData = { ...data, title };
    }
    try {
      await saveReport(reportData);
      onSave?.(reportData);
    } catch (err) {
      console.error('[reports] 저장 오류:', err);
      alert('보고서 저장 중 오류가 발생했습니다.');
    }
  }, [data, onSave]);

  const pages = [
    { label: '1. 사고 정보', node: <Page1 data={data} editing={editing} onChange={setData} /> },
    {
      label: '2. 해양기상 + 확산예측',
      node: <Page2 data={data} editing={editing} onChange={setData} />,
    },
    { label: '3. 분석', node: <Page3 data={data} editing={editing} onChange={setData} /> },
    { label: '4. 민감자원', node: <Page4 data={data} editing={editing} onChange={setData} /> },
    { label: '5. 통합민감도', node: <Page5 data={data} editing={editing} onChange={setData} /> },
    { label: '6. 방제전략', node: <Page6 data={data} editing={editing} onChange={setData} /> },
    { label: '7. 동원 결과', node: <Page7 data={data} editing={editing} onChange={setData} /> },
  ];

  return (
    <div className="w-full">
      {/* Toolbar */}
      <div className="flex items-center justify-between mb-5 flex-wrap gap-3">
        <div className="flex items-center gap-2.5">
          {onBack && (
            <button
              onClick={onBack}
              className="px-3 py-1.5 text-label-1 font-semibold text-fg-sub bg-transparent border-none cursor-pointer"
            >
              ← 돌아가기
            </button>
          )}
          <h2 className="text-title-1 font-bold">
            {editing ? (
              <input
                value={data.title}
                onChange={(e) => setData({ ...data, title: e.target.value })}
                placeholder="보고서 제목 입력"
                className="text-title-1 font-bold bg-bg-base border border-[var(--stroke-light)] rounded px-2.5 py-1 outline-none w-full max-w-[600px]"
              />
            ) : (
              data.title || '유류오염사고 대응지원 상황도'
            )}
          </h2>
          <span
            className="px-2.5 py-[3px] text-label-2 font-semibold rounded border"
            style={
              editing
                ? {
                    background: 'rgba(251,191,36,0.15)',
                    color: '#f59e0b',
                    borderColor: 'rgba(251,191,36,0.3)',
                  }
                : {
                    background: 'rgba(6,182,212,0.15)',
                    color: 'var(--color-accent)',
                    borderColor: 'rgba(6,182,212,0.3)',
                  }
            }
          >
            {editing ? '편집 중' : mode === 'preview' ? '샘플' : '보기'}
          </span>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => setViewMode('all')}
            className="px-3.5 py-1.5 text-label-2 font-semibold rounded cursor-pointer"
            style={{
              border:
                viewMode === 'all'
                  ? '1px solid var(--color-accent)'
                  : '1px solid var(--stroke-default)',
              background: viewMode === 'all' ? 'rgba(6,182,212,0.1)' : 'var(--bg-elevated)',
              color: viewMode === 'all' ? 'var(--color-accent)' : 'var(--fg-disabled)',
            }}
          >
            전체 보기
          </button>
          <button
            onClick={() => setViewMode('page')}
            className="px-3.5 py-1.5 text-label-2 font-semibold rounded cursor-pointer"
            style={{
              border:
                viewMode === 'page'
                  ? '1px solid var(--color-accent)'
                  : '1px solid var(--stroke-default)',
              background: viewMode === 'page' ? 'rgba(6,182,212,0.1)' : 'var(--bg-elevated)',
              color: viewMode === 'page' ? 'var(--color-accent)' : 'var(--fg-disabled)',
            }}
          >
            페이지별
          </button>
          {editing && (
            <button
              onClick={handleSave}
              className="px-4 py-1.5 text-label-2 font-bold rounded cursor-pointer border border-[#22c55e] bg-[rgba(34,197,94,0.15)] text-color-success"
            >
              저장
            </button>
          )}
          <button
            onClick={() => window.print()}
            className="px-3.5 py-1.5 text-label-2 font-semibold rounded cursor-pointer border border-[var(--color-danger)] bg-[rgba(239,68,68,0.1)] text-color-danger"
          >
            인쇄 / PDF
          </button>
        </div>
      </div>

      {/* Page tabs */}
      {viewMode === 'page' && (
        <div className="flex gap-1 mb-4 flex-wrap">
          {pages.map((p, i) => (
            <button
              key={i}
              onClick={() => setCurrentPage(i)}
              className="px-3 py-1.5 text-label-2 font-semibold rounded cursor-pointer"
              style={{
                border:
                  currentPage === i
                    ? '1px solid var(--color-accent)'
                    : '1px solid var(--stroke-default)',
                background: currentPage === i ? 'rgba(6,182,212,0.15)' : 'transparent',
                color: currentPage === i ? 'var(--color-accent)' : 'var(--fg-disabled)',
              }}
            >
              {p.label}
            </button>
          ))}
        </div>
      )}

      {/* Pages */}
      <div id="report-print-area" className="w-full">
        {viewMode === 'all' ? (
          pages.map((p, i) => <div key={i}>{p.node}</div>)
        ) : (
          <div>
            {pages[currentPage].node}
            <div className="flex justify-center gap-2 mt-4">
              <button
                onClick={() => setCurrentPage((p) => Math.max(0, p - 1))}
                disabled={currentPage === 0}
                className="px-5 py-2 text-label-1 font-semibold rounded border border-stroke bg-bg-elevated cursor-pointer"
                style={{
                  color: currentPage === 0 ? 'var(--fg-disabled)' : 'var(--fg-default)',
                  opacity: currentPage === 0 ? 0.4 : 1,
                }}
              >
                이전
              </button>
              <span className="px-4 py-2 text-label-1 text-fg-sub">
                {currentPage + 1} / {pages.length}
              </span>
              <button
                onClick={() => setCurrentPage((p) => Math.min(pages.length - 1, p + 1))}
                disabled={currentPage === pages.length - 1}
                className="px-5 py-2 text-label-1 font-semibold rounded cursor-pointer"
                style={{
                  border: '1px solid var(--color-accent)',
                  background: 'rgba(6,182,212,0.1)',
                  color:
                    currentPage === pages.length - 1 ? 'var(--fg-disabled)' : 'var(--color-accent)',
                  opacity: currentPage === pages.length - 1 ? 0.4 : 1,
                }}
              >
                다음
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
