import { getRecentObservation, OBS_STATION_CODES } from './khoaApi';
import type { WeatherSnapshot } from '@common/store/weatherSnapshotStore';

const CARDINAL_LABELS = [
  'N',
  'NNE',
  'NE',
  'ENE',
  'E',
  'ESE',
  'SE',
  'SSE',
  'S',
  'SSW',
  'SW',
  'WSW',
  'W',
  'WNW',
  'NW',
  'NNW',
] as const;

export function degreesToCardinal(deg: number): string {
  const idx = Math.round((((deg % 360) + 360) % 360) / 22.5) % 16;
  return CARDINAL_LABELS[idx];
}

const BASE_STATIONS = [
  { id: 'incheon', name: '인천', location: { lat: 37.45, lon: 126.43 } },
  { id: 'ulsan', name: '울산', location: { lat: 35.52, lon: 129.38 } },
  { id: 'yeosu', name: '여수', location: { lat: 34.74, lon: 127.75 } },
  { id: 'jeju', name: '제주', location: { lat: 33.51, lon: 126.53 } },
  { id: 'pohang', name: '포항', location: { lat: 36.03, lon: 129.38 } },
  { id: 'mokpo', name: '목포', location: { lat: 34.78, lon: 126.38 } },
  { id: 'gunsan', name: '군산', location: { lat: 35.97, lon: 126.7 } },
  { id: 'sokcho', name: '속초', location: { lat: 38.21, lon: 128.59 } },
  { id: 'tongyeong', name: '통영', location: { lat: 34.83, lon: 128.43 } },
  { id: 'donghae', name: '동해', location: { lat: 37.52, lon: 129.14 } },
];

export async function fetchWeatherSnapshotForCoord(
  lat: number,
  lon: number,
): Promise<WeatherSnapshot> {
  const nearest = BASE_STATIONS.reduce((best, s) => {
    const d = (s.location.lat - lat) ** 2 + (s.location.lon - lon) ** 2;
    const bd = (best.location.lat - lat) ** 2 + (best.location.lon - lon) ** 2;
    return d < bd ? s : best;
  });

  const r = (n: number) => Math.round(n * 10) / 10;

  const obsCode = OBS_STATION_CODES[nearest.id];
  const obs = obsCode ? await getRecentObservation(obsCode) : null;

  const windIcon = (spd: number) => (spd > 12 ? '🌧️' : spd > 8 ? '🌦️' : spd > 5 ? '⛅' : '☀️');
  const mockAstronomy = {
    sunrise: '07:12',
    sunset: '17:58',
    moonrise: '19:35',
    moonset: '01:50',
    moonPhase: '상현달 14일',
    tidalRange: 6.7,
  };

  if (obs) {
    const windSpeed = r(obs.wind_speed ?? 8.0);
    const windDir = obs.wind_dir ?? 315;
    const waterTemp = r(obs.water_temp ?? 8.0);
    const airTemp = r(obs.air_temp ?? waterTemp);
    const pressure = Math.round(obs.air_pres ?? 1013);
    const waveHeight = r(1.0 + windSpeed * 0.1);

    return {
      stationName: nearest.name,
      capturedAt: new Date().toISOString(),
      wind: {
        speed: windSpeed,
        direction: windDir,
        directionLabel: degreesToCardinal(windDir),
        speed_1k: r(windSpeed * 0.8),
        speed_3k: r(windSpeed * 1.2),
      },
      wave: {
        height: waveHeight,
        maxHeight: r(waveHeight * 1.6),
        period: Math.floor(4 + windSpeed * 0.3),
        direction: degreesToCardinal(windDir + 45),
      },
      temperature: { current: waterTemp, feelsLike: r(airTemp - windSpeed * 0.3) },
      pressure,
      visibility: pressure > 1010 ? 15 : 10,
      salinity: 31.2,
      forecast: [0, 3, 6, 9, 12].map((h, i) => ({
        time: `${h}시`,
        icon: windIcon(windSpeed + (i * 0.3 - 0.3)),
        temperature: r(airTemp - i * 0.3),
        windSpeed: r(windSpeed + (i * 0.2 - 0.2)),
      })),
      astronomy: mockAstronomy,
      alert: windSpeed > 14 ? '풍랑주의보 예상' : undefined,
    };
  }

  // Fallback: 시드 기반 더미
  const seed = nearest.location.lat * 100 + nearest.location.lon;
  const windSpeed = r(6 + (seed % 7));
  const windDir = [0, 45, 90, 135, 180, 225, 270, 315][Math.floor(seed) % 8];
  const waveHeight = r(0.8 + (seed % 20) / 10);
  const temp = r(5 + (seed % 8));

  return {
    stationName: nearest.name,
    capturedAt: new Date().toISOString(),
    wind: {
      speed: windSpeed,
      direction: windDir,
      directionLabel: degreesToCardinal(windDir),
      speed_1k: r(windSpeed * 0.8),
      speed_3k: r(windSpeed * 1.2),
    },
    wave: {
      height: waveHeight,
      maxHeight: r(waveHeight * 1.6),
      period: 4 + (Math.floor(seed) % 3),
      direction: degreesToCardinal(windDir + 45),
    },
    temperature: { current: temp, feelsLike: r(temp - windSpeed * 0.3) },
    pressure: 1010 + (Math.floor(seed) % 12),
    visibility: 12 + (Math.floor(seed) % 10),
    salinity: 31.2,
    forecast: [0, 3, 6, 9, 12].map((h, i) => ({
      time: `${h}시`,
      icon: windIcon(windSpeed + (i * 0.3 - 0.3)),
      temperature: r(temp - i * 0.3),
      windSpeed: r(windSpeed + (i * 0.2 - 0.2)),
    })),
    astronomy: mockAstronomy,
    alert: windSpeed > 14 ? '풍랑주의보 예상' : undefined,
  };
}
