'use client';

import './world-map.scss';
import { useMemo, useState } from 'react';
import { EXCHANGE_GEO, moveDir, formatFlucRate, formatIndexClose, type WorldIndexRow } from '@/types/worldIndex';
import { WORLD_LAND_PATH } from './worldLandPath';

// 등거리(plate carrée) 투영 — viewBox 1000×400, 경도 -180~180 → x, 위도 84~-60 → y (남극 크롭, 등scale).
// WORLD_LAND_PATH(실제 Natural Earth 110m 육지) 도 동일 투영으로 생성되어 핀과 정확히 정렬된다.
const VW = 1000;
const VH = 400;
const LAT_MAX = 84;
const LAT_SPAN = 144;
const project = (lat: number, lng: number) => ({
	x: ((lng + 180) / 360) * VW,
	y: ((LAT_MAX - lat) / LAT_SPAN) * VH
});

// 위/경도 격자선 (크롭 위도 범위 내)
const LNG_LINES = [-150, -120, -90, -60, -30, 0, 30, 60, 90, 120, 150];
const LAT_LINES = [-40, -20, 0, 20, 40, 60];

type Props = {
	rows: WorldIndexRow[];
};

type Pin = {
	row: WorldIndexRow;
	label: string;
	x: number;
	y: number;
	dir: 'up' | 'down' | 'flat';
	radius: number;
};

export default function WorldMarketMap({ rows }: Props)
{
	const [active, setActive] = useState<string|null>(null);

	// 좌표를 아는 국가만 핀으로. 등락 크기에 따라 반경 가변(6~10).
	const pins = useMemo<Pin[]>(() => {
		return rows
			.map((row) => {
				const geo = EXCHANGE_GEO[row.countryCode];
				if (!geo) {
					return null;
				}
				const { x, y } = project(geo.lat, geo.lng);
				const radius = Math.min(10, 6 + Math.abs(row.flucRateBp) / 80);
				return { row, label: geo.label, x, y, dir: moveDir(row.flucRateBp), radius };
			})
			.filter((c): c is Pin => c !== null);
	}, [rows]);

	// 기준일 = 핀 중 가장 최근 거래일
	const asOf = useMemo(() => {
		return rows.reduce<string|null>((max, c) => (max === null || c.tradeDate > max ? c.tradeDate : max), null);
	}, [rows]);

	const activePin = pins.find((c) => c.row.countryCode === active) ?? null;

	return (
		<section className='world-map' aria-label='세계 주요국 증시지수'>
			<div className='world-map__head'>
				<h2 className='world-map__title'>세계 증시</h2>
				<div className='world-map__meta'>
					<span className='world-map__legend'>
						<i className='world-map__dot world-map__dot--up' aria-hidden='true' />상승
						<i className='world-map__dot world-map__dot--down' aria-hidden='true' />하락
					</span>
					{asOf && <span className='world-map__asof'>기준 {asOf}</span>}
				</div>
			</div>

			<div className='world-map__stage'>
				{pins.length === 0 ? (
					<div className='world-map__empty'>표시할 지수 데이터가 없습니다.</div>
				) : (
					<svg
						className='world-map__svg'
						viewBox={`0 0 ${VW} ${VH}`}
						role='img'
						aria-label='세계지도 위 주요국 증시지수 핀'
						preserveAspectRatio='xMidYMid meet'
					>
						<defs>
							<radialGradient id='wm-ocean' cx='50%' cy='38%' r='75%'>
								<stop offset='0%' stopColor='var(--az-map-ocean-1)' />
								<stop offset='100%' stopColor='var(--az-map-ocean-2)' />
							</radialGradient>
							<filter id='wm-glow' x='-60%' y='-60%' width='220%' height='220%'>
								<feGaussianBlur stdDeviation='4' result='b' />
								<feMerge>
									<feMergeNode in='b' />
									<feMergeNode in='SourceGraphic' />
								</feMerge>
							</filter>
						</defs>

						{/* 대양 */}
						<rect x='0' y='0' width={VW} height={VH} rx='16' fill='url(#wm-ocean)' />

						{/* 격자선 */}
						<g className='world-map__grid'>
							{LNG_LINES.map((lng) => {
								const x = ((lng + 180) / 360) * VW;
								return <line key={`lng-${lng}`} x1={x} y1='0' x2={x} y2={VH} />;
							})}
							{LAT_LINES.map((lat) => {
								const y = ((LAT_MAX - lat) / LAT_SPAN) * VH;
								return <line key={`lat-${lat}`} x1='0' y1={y} x2={VW} y2={y} />;
							})}
						</g>

						{/* 대륙 (실제 Natural Earth 110m 육지) */}
						<g className='world-map__land'>
							<path d={WORLD_LAND_PATH} />
						</g>

						{/* 핀 */}
						<g className='world-map__pins'>
							{pins.map((pin) => {
								const isActive = pin.row.countryCode === active;
								return (
									<g
										key={pin.row.countryCode}
										className={`world-map__pin world-map__pin--${pin.dir}${isActive ? ' is-active' : ''}`}
										transform={`translate(${pin.x} ${pin.y})`}
										role='button'
										tabIndex={0}
										aria-label={`${pin.label} ${pin.row.name} ${formatFlucRate(pin.row.flucRateBp)}`}
										onMouseEnter={() => setActive(pin.row.countryCode)}
										onMouseLeave={() => setActive((cur) => (cur === pin.row.countryCode ? null : cur))}
										onFocus={() => setActive(pin.row.countryCode)}
										onBlur={() => setActive((cur) => (cur === pin.row.countryCode ? null : cur))}
									>
										{pin.dir !== 'flat' && <circle className='world-map__pulse' r={pin.radius} />}
										<circle className='world-map__pin-dot' r={pin.radius} />
										<circle className='world-map__pin-core' r={pin.radius / 2.6} />
									</g>
								);
							})}
						</g>
					</svg>
				)}

				{/* 툴팁 — 활성 핀 기준 % 위치 (viewBox 비율) */}
				{activePin && (
					<div
						className='world-map__tip'
						style={{ left: `${(activePin.x / VW) * 100}%`, top: `${(activePin.y / VH) * 100}%` }}
						role='status'
					>
						<div className='world-map__tip-head'>
							<span className='world-map__tip-country'>{activePin.label}</span>
							<span className='world-map__tip-name'>{activePin.row.name}</span>
						</div>
						<div className='world-map__tip-close'>{formatIndexClose(activePin.row.close)}</div>
						<div className={`world-map__tip-change world-map__tip-change--${activePin.dir}`}>
							{formatFlucRate(activePin.row.flucRateBp)}
							<span className='world-map__tip-exch'>{activePin.row.exchangeName}</span>
						</div>
					</div>
				)}
			</div>
		</section>
	);
}
