import { useCallback, useMemo, useState } from 'react';
import { useParams, useSearchParams } from 'react-router-dom';
import { ApiRequestError } from '../../api/client';
import { utilityApi } from '../../api/endpoints';
import { Button } from '../../components/ui/Button';
import type {
  UtilityDevice,
  UtilityOrderDto,
  UtilityQuote,
  WiringResult,
  WiringTerminal,
} from '../../api/types';
import { WiringCanvas } from './WiringCanvas';
import './utility.css';

/*
 * SCR-07 유틸리티 배선 뷰 (M4a 견적 + M4b 배선). Stitch utility_wiring_view 이식.
 * - 좌: 기기 목록 빌더 → quote(완성 API). 중앙: WiringCanvas(경로). 우: 자동 견적 패널 + 신청 CTA.
 * - quote는 완성 엔드포인트, wiring/order는 501 → degraded 클라이언트 산출/안내.
 */

type UtilTab = 'power' | 'network' | 'water';

// 부스 로컬 기준 폴리곤(6×3m). ★부스 geometry 엔드포인트 부재 → 고정(경계면 이슈 기록).
const BOOTH_POLY: number[][] = [
  [0, 0],
  [6, 0],
  [6, 3],
  [0, 3],
  [0, 0],
];

const DEFAULT_DEVICES: UtilityDevice[] = [
  { name: '로봇 시연장비', count: 2, powerKw: 1.5 },
  { name: 'LED 스포트 조명', count: 6, powerKw: 0.3 },
];

/** degraded 배선: 최근접 트렌치 교차점(3m 그리드)에서 단말까지 L자 경로 산출. */
function degradedWiring(terminals: WiringTerminal[]): WiringResult {
  const snap = (v: number) => Math.round(v / 3) * 3;
  return {
    assumedTrench: true,
    paths: terminals.map((t) => {
      const [tx, ty] = t.position;
      const sx = snap(tx);
      const sy = snap(ty);
      const coords = [
        [sx, sy],
        [tx, sy],
        [tx, ty],
      ];
      let lengthM = 0;
      for (let i = 1; i < coords.length; i += 1) {
        lengthM += Math.hypot(coords[i][0] - coords[i - 1][0], coords[i][1] - coords[i - 1][1]);
      }
      const color = t.kind === 'power' ? 'red' : t.kind === 'network' ? 'blue' : 'green';
      const label =
        t.kind === 'power'
          ? `${t.kw ?? ''}kW`
          : t.kind === 'network'
            ? '유선 회선'
            : '급배수';
      return { kind: t.kind, color, coords, lengthM: Math.round(lengthM * 100) / 100, label };
    }),
  };
}

export function UtilityWiringPage() {
  const { eventId = '', boothId = '' } = useParams();
  const [searchParams] = useSearchParams();
  const hallId = searchParams.get('hallId') ?? 'H7';

  const [tab, setTab] = useState<UtilTab>('power');
  const [devices, setDevices] = useState<UtilityDevice[]>(DEFAULT_DEVICES);
  const [networkLines, setNetworkLines] = useState(1);
  const [plumbingOutlets, setPlumbingOutlets] = useState(1);
  const [airOutlets, setAirOutlets] = useState(0);

  const [quote, setQuote] = useState<UtilityQuote | null>(null);
  const [wiring, setWiring] = useState<WiringResult | null>(null);
  const [order, setOrder] = useState<UtilityOrderDto | null>(null);
  const [busy, setBusy] = useState(false);
  const [notice, setNotice] = useState<string | null>(null);
  const [selectedTerminal, setSelectedTerminal] = useState<number | null>(null);

  // 필요 전력(로컬 미리보기 — 서버 quote가 권위).
  const requestedKw = useMemo(() => {
    const total = devices.reduce((s, d) => s + d.count * d.powerKw, 0);
    return Math.ceil(total);
  }, [devices]);
  const distributionBox = useMemo(() => Math.ceil(requestedKw / 11), [requestedKw]);

  // 단말 좌표(부스 내부 배치 — power 좌하단, network 좌상단, water 우하단).
  const terminals: WiringTerminal[] = useMemo(() => {
    const out: WiringTerminal[] = [];
    if (requestedKw > 0) out.push({ kind: 'power', position: [4.5, 2.2], kw: requestedKw });
    for (let i = 0; i < networkLines; i += 1)
      out.push({ kind: 'network', position: [1.2, 0.8 + i * 0.6] });
    for (let i = 0; i < plumbingOutlets; i += 1)
      out.push({ kind: 'plumbing', position: [5.2, 0.8 + i * 0.6] });
    for (let i = 0; i < airOutlets; i += 1)
      out.push({ kind: 'air', position: [3.0, 0.6 + i * 0.6] });
    return out;
  }, [requestedKw, networkLines, plumbingOutlets, airOutlets]);

  const buildRequest = useCallback(
    () => ({
      devices,
      networkWiredLines: networkLines,
      plumbingOutlets,
      compressedAirOutlets: airOutlets,
    }),
    [devices, networkLines, plumbingOutlets, airOutlets],
  );

  const recalc = useCallback(async () => {
    setBusy(true);
    setNotice(null);
    // quote (완성 API)
    try {
      const q = await utilityApi.quote(eventId, boothId, buildRequest());
      setQuote(q);
    } catch (err) {
      if (err instanceof ApiRequestError && err.code === 'NOT_IMPLEMENTED') {
        setNotice('견적 엔진이 준비 중입니다(로컬 추정 표시).');
      } else {
        setNotice(err instanceof ApiRequestError ? err.message : '견적 계산 중 오류가 발생했습니다.');
      }
    }
    // wiring (501 → degraded 클라이언트 산출)
    try {
      const w = await utilityApi.wiring(eventId, boothId, hallId, { terminals });
      setWiring(w);
    } catch (err) {
      if (err instanceof ApiRequestError && err.code === 'NOT_IMPLEMENTED') {
        setWiring(degradedWiring(terminals));
      }
    }
    setBusy(false);
  }, [eventId, boothId, hallId, buildRequest, terminals]);

  const submitOrder = useCallback(async () => {
    setBusy(true);
    setNotice(null);
    try {
      const o = await utilityApi.order(eventId, boothId, buildRequest());
      setOrder(o);
    } catch (err) {
      if (err instanceof ApiRequestError && err.code === 'NOT_IMPLEMENTED') {
        setNotice('신청 제출 경로가 준비 중입니다(백엔드 위치표시도 생성 대기).');
      } else {
        setNotice(err instanceof ApiRequestError ? err.message : '신청 제출 중 오류가 발생했습니다.');
      }
    }
    setBusy(false);
  }, [eventId, boothId, buildRequest]);

  // 렌더용 배선(계산 전이면 degraded 미리보기).
  const wiringView = wiring ?? degradedWiring(terminals);
  const activeQuote = order?.quote ?? quote;

  return (
    <div className="kx-util">
      <header className="kx-util__head">
        <div>
          <h2 className="kx-util__title">부스 {boothId || 'A-102'} · 홀 {hallId}</h2>
          <div className="kx-util__deadline" role="note">
            유틸리티 신청 마감 D-6 · 인터넷은 현장 추가신청 불가
          </div>
        </div>
        <div className="kx-util__tabs" role="tablist" aria-label="유틸리티 종류">
          <TabBtn active={tab === 'power'} onClick={() => setTab('power')} label="전기" />
          <TabBtn active={tab === 'network'} onClick={() => setTab('network')} label="네트워크·전화" />
          <TabBtn active={tab === 'water'} onClick={() => setTab('water')} label="급배수·압축공기" />
        </div>
      </header>

      <div className="kx-util__body">
        {/* 좌: 입력 빌더 */}
        <aside className="kx-util__left" aria-label="유틸리티 입력">
          {tab === 'power' && (
            <section className="kx-util__section">
              <h3>사용 기기 입력</h3>
              <div className="kx-devtable">
                <div className="kx-devtable__head">
                  <span>기기명</span>
                  <span>수량</span>
                  <span>kW</span>
                  <span aria-hidden="true" />
                </div>
                {devices.map((d, i) => (
                  <div className="kx-devtable__row" key={i}>
                    <input
                      aria-label={`기기 ${i + 1} 이름`}
                      value={d.name}
                      onChange={(e) =>
                        setDevices((ds) => ds.map((x, j) => (j === i ? { ...x, name: e.target.value } : x)))
                      }
                    />
                    <input
                      type="number"
                      className="tnum"
                      aria-label={`기기 ${i + 1} 수량`}
                      value={d.count}
                      min={0}
                      onChange={(e) =>
                        setDevices((ds) =>
                          ds.map((x, j) => (j === i ? { ...x, count: Number(e.target.value) } : x)),
                        )
                      }
                    />
                    <input
                      type="number"
                      className="tnum"
                      step={0.1}
                      aria-label={`기기 ${i + 1} 소비전력`}
                      value={d.powerKw}
                      min={0}
                      onChange={(e) =>
                        setDevices((ds) =>
                          ds.map((x, j) => (j === i ? { ...x, powerKw: Number(e.target.value) } : x)),
                        )
                      }
                    />
                    <button
                      className="kx-devtable__del"
                      aria-label={`기기 ${i + 1} 삭제`}
                      onClick={() => setDevices((ds) => ds.filter((_, j) => j !== i))}
                    >
                      ✕
                    </button>
                  </div>
                ))}
              </div>
              <button
                className="kx-util__addrow"
                onClick={() => setDevices((ds) => [...ds, { name: '신규 기기', count: 1, powerKw: 0.5 }])}
              >
                + 기기 추가
              </button>

              <div className="kx-util__compute tnum">
                <div>
                  필요 용량 <strong>{requestedKw}kW</strong>
                  <span className="kx-util__arrow">→</span> 신청 {requestedKw}kW
                </div>
                <div>분전반 50A × {distributionBox}식 자동 산출</div>
              </div>
            </section>
          )}

          {tab === 'network' && (
            <section className="kx-util__section">
              <h3>네트워크·전화</h3>
              <NumRow label="유선 인터넷 회선" value={networkLines} onChange={setNetworkLines} />
              <p className="kx-util__hint">단말 위치는 도면에서 드래그로 미세 조정할 수 있습니다.</p>
            </section>
          )}

          {tab === 'water' && (
            <section className="kx-util__section">
              <h3>급배수·압축공기</h3>
              <NumRow label="급배수 구" value={plumbingOutlets} onChange={setPlumbingOutlets} />
              <NumRow label="압축공기 구" value={airOutlets} onChange={setAirOutlets} />
            </section>
          )}

          <Button variant="secondary" block onClick={recalc} disabled={busy}>
            {busy ? '계산 중…' : '견적·배선 계산'}
          </Button>
        </aside>

        {/* 중앙: 배선 캔버스 */}
        <section className="kx-util__canvas">
          <WiringCanvas
            boothPolygon={BOOTH_POLY}
            paths={wiringView.paths}
            terminals={terminals}
            assumedTrench={wiringView.assumedTrench}
            selectedTerminalIdx={selectedTerminal}
            onSelectTerminal={setSelectedTerminal}
          />
        </section>

        {/* 우: 자동 견적 패널 */}
        <aside className="kx-util__right" aria-label="자동 견적">
          <h3 className="kx-quote__title">자동 견적</h3>
          {activeQuote ? (
            <>
              <ul className="kx-quote__lines tnum">
                {activeQuote.lines.map((l, i) => (
                  <li key={i}>
                    <span className="kx-quote__label">
                      {l.label}
                      {l.qty > 1 && <em> ×{l.qty}</em>}
                    </span>
                    <span className="kx-quote__amount">₩{l.amount.toLocaleString()}</span>
                  </li>
                ))}
              </ul>
              <div className="kx-quote__total tnum">
                <span>합계</span>
                <strong>₩{activeQuote.total.toLocaleString()}</strong>
              </div>
              <p className="kx-quote__disclaimer">{activeQuote.disclaimer}</p>
              <p className="kx-quote__ruleset">요율 {activeQuote.rulesetVersion}</p>
            </>
          ) : (
            <p className="kx-quote__empty">
              기기·회선을 입력하고 <strong>견적·배선 계산</strong>을 누르면 자동 견적이 표시됩니다.
            </p>
          )}

          {order ? (
            <div className="kx-quote__submitted" role="status">
              <p className="kx-quote__submitted-title">신청 제출됨</p>
              <p>{order.supplyTiming}</p>
              <p className="kx-quote__relay">{order.relayNotice}</p>
              <a className="kx-quote__diagram" href={order.locationDiagramUrl}>
                위치표시도 보기
              </a>
            </div>
          ) : (
            <Button block onClick={submitOrder} disabled={busy || !activeQuote}>
              위치표시도 생성 및 신청
            </Button>
          )}

          {notice && (
            <p className="kx-util__banner" role="status">
              {notice}
            </p>
          )}
        </aside>
      </div>
    </div>
  );
}

function TabBtn({ active, onClick, label }: { active: boolean; onClick: () => void; label: string }) {
  return (
    <button
      role="tab"
      aria-selected={active}
      className={`kx-util__tab ${active ? 'is-active' : ''}`}
      onClick={onClick}
    >
      {label}
    </button>
  );
}

function NumRow({ label, value, onChange }: { label: string; value: number; onChange: (v: number) => void }) {
  return (
    <label className="kx-util__numrow">
      <span>{label}</span>
      <input
        type="number"
        className="tnum"
        min={0}
        value={value}
        onChange={(e) => onChange(Math.max(0, Number(e.target.value)))}
      />
    </label>
  );
}
