import axios from 'axios';

const API_KEY = import.meta.env.VITE_WEATHER_API_KEY;
const BASE_URL = 'https://apihub.kma.go.kr/api/typ01/url';

// 위경도 → 격자 변환 (기상청 제공 알고리즘)
export function latLngToGrid(lat: number, lng: number) {
  const RE = 6371.00877; // 지구 반경(km)
  const GRID = 5.0; // 격자 간격(km)
  const SLAT1 = 30.0; // 표준위도1
  const SLAT2 = 60.0; // 표준위도2
  const OLON = 126.0; // 기준점 경도
  const OLAT = 38.0; // 기준점 위도
  const XO = 43; // 기준점 X좌표
  const YO = 136; // 기준점 Y좌표

  const DEGRAD = Math.PI / 180.0;
  const re = RE / GRID;
  const slat1 = SLAT1 * DEGRAD;
  const slat2 = SLAT2 * DEGRAD;
  const olon = OLON * DEGRAD;
  const olat = OLAT * DEGRAD;

  let sn = Math.tan(Math.PI * 0.25 + slat2 * 0.5) / Math.tan(Math.PI * 0.25 + slat1 * 0.5);
  sn = Math.log(Math.cos(slat1) / Math.cos(slat2)) / Math.log(sn);
  let sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);
  sf = (Math.pow(sf, sn) * Math.cos(slat1)) / sn;
  let ro = Math.tan(Math.PI * 0.25 + olat * 0.5);
  ro = (re * sf) / Math.pow(ro, sn);

  let ra = Math.tan(Math.PI * 0.25 + lat * DEGRAD * 0.5);
  ra = (re * sf) / Math.pow(ra, sn);
  let theta = lng * DEGRAD - olon;
  if (theta > Math.PI) theta -= 2.0 * Math.PI;
  if (theta < -Math.PI) theta += 2.0 * Math.PI;
  theta *= sn;

  const x = Math.floor(ra * Math.sin(theta) + XO + 0.5);
  const y = Math.floor(ro - ra * Math.cos(theta) + YO + 0.5);

  return { nx: x, ny: y };
}

// 현재 날짜/시간을 기상청 API 형식으로 변환
export function getCurrentBaseTime() {
  const now = new Date();
  const hours = now.getHours();
  const minutes = now.getMinutes();

  // 기상청 API는 매시간 40분에 업데이트되므로, 40분 이전이면 이전 시간 사용
  let baseHour = hours;
  if (minutes < 40) {
    baseHour = hours - 1;
    if (baseHour < 0) baseHour = 23;
  }

  const baseDate = now.toISOString().slice(0, 10).replace(/-/g, '');
  const baseTime = String(baseHour).padStart(2, '0') + '00';

  return { baseDate, baseTime };
}

// 초단기실황 조회 (현재 기상 상태)
export async function getUltraShortNowcast(lat: number, lng: number) {
  const { nx, ny } = latLngToGrid(lat, lng);
  const { baseDate, baseTime } = getCurrentBaseTime();

  try {
    const response = await axios.get(`${BASE_URL}/getUltraSrtNcst`, {
      params: {
        serviceKey: API_KEY,
        numOfRows: 10,
        pageNo: 1,
        base_date: baseDate,
        base_time: baseTime,
        nx,
        ny,
        dataType: 'JSON',
      },
    });

    const items = response.data.response.body.items.item;

    // 데이터 파싱
    const weather: Record<string, number> = {};
    items.forEach((item: Record<string, string>) => {
      switch (item.category) {
        case 'T1H': // 기온
          weather.temperature = parseFloat(item.obsrValue);
          break;
        case 'RN1': // 강수량
          weather.rainfall = parseFloat(item.obsrValue);
          break;
        case 'WSD': // 풍속
          weather.windSpeed = parseFloat(item.obsrValue);
          break;
        case 'VEC': // 풍향
          weather.windDirection = parseInt(item.obsrValue);
          break;
        case 'REH': // 습도
          weather.humidity = parseInt(item.obsrValue);
          break;
        case 'PTY': // 강수형태
          weather.precipType = parseInt(item.obsrValue);
          break;
      }
    });

    return weather;
  } catch (error) {
    console.error('기상청 API 오류:', error);
    throw error;
  }
}

// 단기예보 조회 (최대 72시간)
export async function getShortForecast(lat: number, lng: number) {
  const { nx, ny } = latLngToGrid(lat, lng);
  const now = new Date();

  // 단기예보 base_time: 02:00, 05:00, 08:00, 11:00, 14:00, 17:00, 20:00, 23:00
  const baseHours = [2, 5, 8, 11, 14, 17, 20, 23];
  const currentHour = now.getHours();

  const baseHour = baseHours.reduce((prev, curr) => (curr <= currentHour ? curr : prev));

  const baseDate = now.toISOString().slice(0, 10).replace(/-/g, '');
  const baseTime = String(baseHour).padStart(2, '0') + '00';

  try {
    const response = await axios.get(`${BASE_URL}/getVilageFcst`, {
      params: {
        serviceKey: API_KEY,
        numOfRows: 1000,
        pageNo: 1,
        base_date: baseDate,
        base_time: baseTime,
        nx,
        ny,
        dataType: 'JSON',
      },
    });

    const items = response.data.response.body.items.item;

    // 시간별로 그룹화
    const forecastByTime: Record<string, Record<string, string | number>> = {};
    items.forEach((item: Record<string, string>) => {
      const key = `${item.fcstDate}_${item.fcstTime}`;
      if (!forecastByTime[key]) {
        forecastByTime[key] = {
          date: item.fcstDate,
          time: item.fcstTime,
        };
      }

      switch (item.category) {
        case 'TMP': // 기온
          forecastByTime[key].temperature = parseFloat(item.fcstValue);
          break;
        case 'WSD': // 풍속
          forecastByTime[key].windSpeed = parseFloat(item.fcstValue);
          break;
        case 'VEC': // 풍향
          forecastByTime[key].windDirection = parseInt(item.fcstValue);
          break;
        case 'SKY': // 하늘상태
          forecastByTime[key].skyCondition = parseInt(item.fcstValue);
          break;
        case 'POP': // 강수확률
          forecastByTime[key].precipProbability = parseInt(item.fcstValue);
          break;
        case 'WAV': // 파고
          forecastByTime[key].waveHeight = parseFloat(item.fcstValue);
          break;
      }
    });

    return Object.values(forecastByTime);
  } catch (error) {
    console.error('단기예보 API 오류:', error);
    throw error;
  }
}

// 풍향을 16방위로 변환
export function windDirectionToText(degree: number): string {
  const directions = [
    'N',
    'NNE',
    'NE',
    'ENE',
    'E',
    'ESE',
    'SE',
    'SSE',
    'S',
    'SSW',
    'SW',
    'WSW',
    'W',
    'WNW',
    'NW',
    'NNW',
  ];

  const index = Math.round((degree % 360) / 22.5) % 16;
  return directions[index];
}

// 해상 기상 정보 (Mock - 실제로는 해양기상청 API 사용)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function getMarineWeather(lat: number, lng: number) {
  // TODO: 해양기상청 API 연동
  // 현재는 Mock 데이터 반환
  return {
    waveHeight: 1.2, // 파고 (m)
    waveDirection: 135, // 파향 (도)
    wavePeriod: 5.5, // 주기 (초)
    seaTemperature: 12.5, // 수온 (°C)
    currentSpeed: 0.3, // 해류속도 (m/s)
    currentDirection: 180, // 해류방향 (도)
    visibility: 15, // 시정 (km)
  };
}
