/*
 * 관람객 대면 라이브 정보(F-C2 주차 · F-C3 혼잡) — 공개(비로그인) 조회 + 로그인 시 주차권.
 * 백엔드 계약: _workspace/parking_congestion_contract.md (ParkingController·PublicCongestionController).
 * 결제는 mock PG(백엔드). 차량번호 원문 미노출(서버 마스킹). 3상태(로딩/빈/에러) 준수.
 * 자체 스타일(live.css) — 공유 css 무수정. Nifty 카드/그리드 정합.
 */
import { useState } from 'react';
import { useParams } from 'react-router-dom';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { PublicShell } from './PublicShell';
import { liveApi, type CongestionArea, type ParkingLotStatus } from './liveApi';
import { getAccessToken } from '../../api/client';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import { Button } from '../../components/ui/Button';
import { Modal } from '../../components/ui/Modal';
import { IconPin, IconInfo } from './publicIcons';
import './live.css';

const DEFAULT_EVENT_ID = 'e-2026-live';
const won = (n: number) => `₩${n.toLocaleString('ko-KR')}`;

function levelClass(level: string): string {
  return level === 'BUSY' ? 'is-busy' : level === 'NORMAL' ? 'is-normal' : 'is-free';
}

/** 혼잡 영역 칩 목록. */
function AreaRow({ title, areas }: { title: string; areas: CongestionArea[] }) {
  if (areas.length === 0) return null;
  return (
    <div className="kxl-cong__row">
      <span className="kxl-cong__row-label">{title}</span>
      <div className="kxl-cong__chips">
        {areas.map((a) => (
          <span key={a.id} className={`kxl-chip ${levelClass(a.level)}`}>
            {a.label}
            <b>{a.levelLabel}{a.occupancyPercent != null ? ` ${a.occupancyPercent}%` : ''}</b>
          </span>
        ))}
      </div>
    </div>
  );
}

function CongestionCard({ eventId }: { eventId: string }) {
  const q = useQuery({
    queryKey: ['congestion', eventId],
    queryFn: () => liveApi.congestion(eventId),
    retry: false,
    refetchInterval: 30000,
  });

  return (
    <section className="kx-card kxl-cong" aria-label="실시간 혼잡 안내">
      <div className="kxl-cong__head">
        <h2 className="kxl-sec__title">실시간 혼잡 안내</h2>
        {q.data && (
          <span className={`kxl-overall ${levelClass(q.data.overallLevel)}`}>
            전체 {q.data.overallLabel}
          </span>
        )}
      </div>
      {q.isLoading ? (
        <Skeleton height={120} radius={12} />
      ) : q.isError ? (
        <ErrorState message="혼잡 정보를 불러오지 못했습니다." onRetry={() => void q.refetch()} />
      ) : q.data ? (
        <>
          <p className="kxl-cong__onsite">
            현재 장내 추정 <b>{q.data.onSiteCount.toLocaleString()}명</b>
          </p>
          <AreaRow title="입장 게이트" areas={q.data.entryGates} />
          <AreaRow title="주차장" areas={q.data.parking} />
          <AreaRow title="인기 공간" areas={q.data.popularSessions} />
          <p className="kxl-updated">업데이트 {q.data.updatedAt.replace('T', ' ').slice(0, 16)}</p>
        </>
      ) : (
        <EmptyState title="혼잡 정보 없음" />
      )}
    </section>
  );
}

interface PurchaseState {
  lot: ParkingLotStatus;
}

function ParkingCard({ eventId }: { eventId: string }) {
  const qc = useQueryClient();
  const authed = !!getAccessToken();
  const [purchase, setPurchase] = useState<PurchaseState | null>(null);
  const [useDate, setUseDate] = useState(() => new Date(Date.now() + 86400000).toISOString().slice(0, 10));
  const [plate, setPlate] = useState('');
  const [payMethod, setPayMethod] = useState('card');
  const [payError, setPayError] = useState('');

  const lotsQ = useQuery({
    queryKey: ['parkingLots', eventId],
    queryFn: () => liveApi.parkingLots(eventId),
    retry: false,
    refetchInterval: 30000,
  });
  const passesQ = useQuery({
    queryKey: ['myPasses'],
    queryFn: () => liveApi.myPasses(),
    enabled: authed,
    retry: false,
  });

  const buyMut = useMutation({
    mutationFn: () =>
      liveApi.purchasePass({
        lotId: purchase!.lot.lotId,
        useDate,
        eventId,
        vehiclePlate: plate.trim() || undefined,
        payMethod,
      }),
    onSuccess: () => {
      setPurchase(null);
      setPlate('');
      setPayError('');
      qc.invalidateQueries({ queryKey: ['myPasses'] });
      qc.invalidateQueries({ queryKey: ['parkingLots', eventId] });
    },
    onError: () => setPayError('주차권 구매에 실패했습니다. 다시 시도해 주세요.'),
  });

  return (
    <section className="kx-card kxl-parking" aria-label="주차 현황">
      <div className="kxl-cong__head">
        <h2 className="kxl-sec__title">주차 현황</h2>
      </div>

      {lotsQ.isLoading ? (
        <div className="kxl-parklist">
          {[0, 1, 2].map((k) => <Skeleton key={k} height={92} radius={12} />)}
        </div>
      ) : lotsQ.isError ? (
        <ErrorState message="주차 현황을 불러오지 못했습니다." onRetry={() => void lotsQ.refetch()} />
      ) : (lotsQ.data ?? []).length === 0 ? (
        <EmptyState title="주차 정보 없음" />
      ) : (
        <div className="kxl-parklist">
          {lotsQ.data!.map((lot) => (
            <div key={lot.lotId} className="kxl-lot">
              <div className="kxl-lot__top">
                <div>
                  <h3 className="kxl-lot__name">
                    <IconPin width={15} height={15} /> {lot.name}
                  </h3>
                  {lot.note && <p className="kxl-lot__note">{lot.note}</p>}
                </div>
                <span className={`kxl-badge ${levelClass(lot.congestionLevel)}`}>{lot.congestionLabel}</span>
              </div>
              <div className="kxl-lot__bar" role="img" aria-label={`점유율 ${lot.occupancyPercent}%`}>
                <span className={`kxl-lot__fill ${levelClass(lot.congestionLevel)}`} style={{ width: `${lot.occupancyPercent}%` }} />
              </div>
              <div className="kxl-lot__meta">
                <span>잔여 <b>{lot.available.toLocaleString()}</b> / {lot.totalCapacity.toLocaleString()}면</span>
                <span>사전권 {won(lot.passPrice)}</span>
                <Button variant="secondary" onClick={() => (authed ? setPurchase({ lot }) : window.alert('주차권 구매는 로그인이 필요합니다.'))}>
                  주차권 구매
                </Button>
              </div>
            </div>
          ))}
        </div>
      )}

      {/* 내 주차권(로그인 시) */}
      {authed && (
        <div className="kxl-mypasses">
          <h3 className="kxl-sec__title kxl-sec__title--sm">내 주차권</h3>
          {passesQ.isLoading ? (
            <Skeleton height={60} radius={10} />
          ) : (passesQ.data?.passes ?? []).length === 0 ? (
            <p className="kxl-empty">보유한 주차권이 없습니다.</p>
          ) : (
            <ul className="kxl-passlist">
              {passesQ.data!.passes.map((p) => (
                <li key={p.passNo} className="kxl-pass">
                  <div>
                    <span className="kxl-pass__no">{p.passNo}</span>
                    <span className="kxl-pass__meta">{p.lotName} · {p.useDate} · {p.vehiclePlateMasked ?? '차량 미등록'}</span>
                  </div>
                  <span className={`kxl-badge ${p.status === 'PAID' ? 'is-free' : 'is-normal'}`}>{p.status}</span>
                </li>
              ))}
            </ul>
          )}
        </div>
      )}

      {/* 구매 모달(공용 Modal 재사용) */}
      <Modal
        open={!!purchase}
        onClose={() => setPurchase(null)}
        title="사전 주차권 구매"
        footer={
          <>
            <Button variant="secondary" onClick={() => setPurchase(null)}>취소</Button>
            <Button onClick={() => buyMut.mutate()} disabled={buyMut.isPending}>
              {buyMut.isPending ? '결제 중…' : `${purchase ? won(purchase.lot.passPrice) : ''} 결제`}
            </Button>
          </>
        }
      >
        {purchase && (
          <div className="kxl-buy">
            <p className="kxl-buy__lot">{purchase.lot.name} · 1일권 {won(purchase.lot.passPrice)}</p>
            <label className="kxl-field">
              <span>이용일</span>
              <input type="date" value={useDate} min={new Date().toISOString().slice(0, 10)} onChange={(e) => setUseDate(e.target.value)} />
            </label>
            <label className="kxl-field">
              <span>차량번호(선택)</span>
              <input type="text" value={plate} placeholder="12가3456" onChange={(e) => setPlate(e.target.value)} />
            </label>
            <label className="kxl-field">
              <span>결제수단</span>
              <select value={payMethod} onChange={(e) => setPayMethod(e.target.value)}>
                <option value="card">카드</option>
                <option value="easy">간편결제</option>
                <option value="bank">계좌이체</option>
              </select>
            </label>
            <p className="kxl-buy__note"><IconInfo width={14} height={14} /> 차량번호는 마스킹 저장되며 원문은 보관하지 않습니다.</p>
            {payError && <p className="kxl-buy__err" role="alert">{payError}</p>}
          </div>
        )}
      </Modal>
    </section>
  );
}

export function PublicLiveInfoPage() {
  const { eventId } = useParams<{ eventId: string }>();
  const ev = eventId ?? DEFAULT_EVENT_ID;
  return (
    <PublicShell active="visit" search={false}>
      <div className="kxl">
        <header className="kxl-hero">
          <h1>현장 라이브 정보</h1>
          <p>실시간 혼잡도와 주차 현황을 확인하고 사전 주차권을 준비하세요.</p>
        </header>
        <div className="kxl-grid">
          <CongestionCard eventId={ev} />
          <ParkingCard eventId={ev} />
        </div>
      </div>
    </PublicShell>
  );
}
