import { useRef, useEffect, useState, useMemo } from 'react';

interface ReconItem {
  id: string;
  name: string;
  type: 'vessel' | 'pollution';
  status: 'complete' | 'processing';
  points: string;
  polygons: string;
  coverage: string;
}

const reconItems: ReconItem[] = [
  {
    id: 'V-001',
    name: '불명선박-A',
    type: 'vessel',
    status: 'complete',
    points: '980K',
    polygons: '38K',
    coverage: '97.1%',
  },
  {
    id: 'V-002',
    name: '불명선박-B',
    type: 'vessel',
    status: 'complete',
    points: '1.2M',
    polygons: '48K',
    coverage: '98.4%',
  },
  {
    id: 'V-003',
    name: '어선 #37',
    type: 'vessel',
    status: 'processing',
    points: '420K',
    polygons: '16K',
    coverage: '64.2%',
  },
  {
    id: 'P-001',
    name: '유류오염-A',
    type: 'pollution',
    status: 'complete',
    points: '560K',
    polygons: '22K',
    coverage: '95.8%',
  },
  {
    id: 'P-002',
    name: '유류오염-B',
    type: 'pollution',
    status: 'processing',
    points: '310K',
    polygons: '12K',
    coverage: '52.1%',
  },
];

function mulberry32(seed: number) {
  let s = seed;
  return () => {
    s |= 0;
    s = (s + 0x6d2b79f5) | 0;
    let t = Math.imul(s ^ (s >>> 15), 1 | s);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

const VESSEL_TILT_X = (17 * Math.PI) / 180;
const POLLUTION_TILT_X = (40 * Math.PI) / 180;

// ─────────────────────────────────────────────
// Vessel3DModel
// ─────────────────────────────────────────────

interface VesselPoint {
  x: number;
  y: number;
  z: number;
  r: number;
  g: number;
  b: number;
  radius: number;
}

interface VesselEdge {
  a: number;
  b: number;
  r: number;
  g: number;
  bCh: number;
  isWaterline: boolean;
}

interface VesselGeometry {
  points: VesselPoint[];
  edges: VesselEdge[];
}

function buildVesselGeometry(): VesselGeometry {
  const rand = mulberry32(42);
  const points: VesselPoint[] = [];
  const edges: VesselEdge[] = [];

  // halfWidth: X축 위치에 따른 선체 단면 반폭
  const halfWidth = (nx: number): number => {
    const t = (nx + 1) / 2; // 0~1 (0=선미, 1=선수)
    if (t > 0.85) return 0.05 + ((1 - t) / 0.15) * 0.18; // 선수: 뾰족
    if (t < 0.1) return 0.05 + (t / 0.1) * 0.22; // 선미: 약간 좁음
    return 0.22 + Math.sin(((t - 0.1) / 0.75) * Math.PI) * 0.08; // 중앙부 불룩
  };

  // 선체 구조점: 20 단면 × 8 둘레점
  const sections = 20;
  const circPts = 8;
  const hullPtStart = 0;
  for (let si = 0; si < sections; si++) {
    const nx = -1 + (si / (sections - 1)) * 2;
    const hw = halfWidth(nx);
    for (let ci = 0; ci < circPts; ci++) {
      const t = (ci / circPts) * Math.PI; // 0~PI (갑판~용골)
      const py = -0.15 - 0.12 * Math.sin(t);
      const pz = hw * Math.cos(t);
      points.push({ x: nx, y: py, z: pz, r: 6, g: 182, b: 212, radius: 1.0 });
    }
  }

  // 선체 표면 랜덤점 2000개
  for (let i = 0; i < 2000; i++) {
    const nx = -1 + rand() * 2;
    const hw = halfWidth(nx);
    const t = rand() * Math.PI;
    const py = -0.15 - 0.12 * Math.sin(t) + (rand() - 0.5) * 0.01;
    const pz = hw * Math.cos(t) + (rand() - 0.5) * 0.01;
    points.push({ x: nx, y: py, z: pz, r: 6, g: 182, b: 212, radius: 0.6 });
  }

  // 갑판 (y=-0.03) 200개
  for (let i = 0; i < 200; i++) {
    const nx = -1 + rand() * 2;
    const hw = halfWidth(nx) * 0.85;
    const pz = (rand() * 2 - 1) * hw;
    points.push({ x: nx, y: -0.03, z: pz, r: 6, g: 182, b: 212, radius: 0.7 });
  }

  // Bridge: 선교 (-0.6 < x < -0.3, -0.03 < y < 0.17)
  for (let i = 0; i < 150; i++) {
    const bx = -0.6 + rand() * 0.3;
    const by = -0.03 + rand() * 0.2;
    const bz = (rand() * 2 - 1) * 0.12;
    points.push({ x: bx, y: by, z: bz, r: 6, g: 182, b: 212, radius: 0.8 });
  }

  // Funnel: 연통 원통 (x=-0.5, y=0.17~0.35)
  for (let i = 0; i < 40; i++) {
    const angle = rand() * Math.PI * 2;
    const fy = 0.17 + rand() * 0.18;
    points.push({
      x: -0.5 + (rand() - 0.5) * 0.04,
      y: fy,
      z: 0.04 * Math.cos(angle),
      r: 239,
      g: 68,
      b: 68,
      radius: 1.0,
    });
  }

  // Wireframe edges: 선체 종방향 (매 2번째 단면)
  for (let ci = 0; ci < circPts; ci++) {
    for (let si = 0; si < sections - 2; si += 2) {
      edges.push({
        a: hullPtStart + si * circPts + ci,
        b: hullPtStart + (si + 2) * circPts + ci,
        r: 6,
        g: 182,
        bCh: 212,
        isWaterline: false,
      });
    }
  }

  // Wireframe edges: 횡방향 (매 4번째 단면)
  for (let si = 0; si < sections; si += 4) {
    for (let ci = 0; ci < circPts - 1; ci++) {
      edges.push({
        a: hullPtStart + si * circPts + ci,
        b: hullPtStart + si * circPts + ci + 1,
        r: 6,
        g: 182,
        bCh: 212,
        isWaterline: false,
      });
    }
    edges.push({
      a: hullPtStart + si * circPts + circPts - 1,
      b: hullPtStart + si * circPts,
      r: 6,
      g: 182,
      bCh: 212,
      isWaterline: false,
    });
  }

  // 수선 (waterline)
  const wlSections = [4, 6, 8, 10, 12, 14, 16];
  wlSections.forEach((si) => {
    if (si < sections - 1) {
      edges.push({
        a: hullPtStart + si * circPts,
        b: hullPtStart + (si + 1) * circPts,
        r: 6,
        g: 182,
        bCh: 212,
        isWaterline: true,
      });
    }
  });

  // Crane 포인트
  const craneData = [
    { x: 0.1, y1: -0.03, y2: 0.18 },
    { x: 0.3, y1: -0.03, y2: 0.15 },
  ];
  craneData.forEach((cr) => {
    for (let i = 0; i < 20; i++) {
      const t = i / 19;
      points.push({
        x: cr.x,
        y: cr.y1 + t * (cr.y2 - cr.y1),
        z: 0,
        r: 249,
        g: 115,
        b: 22,
        radius: 1.2,
      });
    }
    for (let i = 0; i < 12; i++) {
      const t = i / 11;
      points.push({
        x: cr.x + t * -0.08,
        y: cr.y2 - t * 0.1,
        z: 0,
        r: 249,
        g: 115,
        b: 22,
        radius: 1.2,
      });
    }
  });

  // Mast
  for (let i = 0; i < 15; i++) {
    const t = i / 14;
    points.push({ x: -0.45, y: 0.17 + t * 0.15, z: 0, r: 6, g: 182, b: 212, radius: 1.0 });
  }

  return { points, edges };
}

function Vessel3DModel({ viewMode, status }: { viewMode: string; status: string }) {
  const isProcessing = status === 'processing';
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const angleRef = useRef(0);
  const rafRef = useRef<number>(0);

  const W = 480;
  const H = 280;
  const FOV = 3.5;
  const geo = useMemo(() => buildVesselGeometry(), []);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const dpr = window.devicePixelRatio || 1;
    canvas.width = W * dpr;
    canvas.height = H * dpr;
    canvas.style.width = `${W}px`;
    canvas.style.height = `${H}px`;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;
    ctx.scale(dpr, dpr);

    const cx = W / 2;
    const cy = H / 2 + 10;
    const scale3d = 155;

    const project = (
      px: number,
      py: number,
      pz: number,
      angle: number,
    ): { sx: number; sy: number; sc: number } => {
      const cosA = Math.cos(angle);
      const sinA = Math.sin(angle);
      const rx = px * cosA - pz * sinA;
      const rz = px * sinA + pz * cosA;
      const cosT = Math.cos(VESSEL_TILT_X);
      const sinT = Math.sin(VESSEL_TILT_X);
      const ry2 = py * cosT - rz * sinT;
      const rz2 = py * sinT + rz * cosT;
      const sc = FOV / (FOV + rz2 + 1.5);
      return { sx: cx + rx * scale3d * sc, sy: cy - ry2 * scale3d * sc, sc };
    };

    const render = () => {
      ctx.clearRect(0, 0, W, H);
      const angle = angleRef.current;
      const alphaBase = isProcessing ? 0.25 : 1.0;

      const showPoints = viewMode === 'point' || viewMode === '3d';
      const showWire = viewMode === 'wire' || viewMode === '3d';

      // 에지 (wireframe)
      if (showWire) {
        geo.edges.forEach((edge) => {
          const ptA = geo.points[edge.a];
          const ptB = geo.points[edge.b];
          if (!ptA || !ptB) return;
          const projA = project(ptA.x, ptA.y, ptA.z, angle);
          const projB = project(ptB.x, ptB.y, ptB.z, angle);
          const avgSc = (projA.sc + projB.sc) / 2;
          const brightness = 0.3 + avgSc * 0.5;
          const lineAlpha =
            (edge.isWaterline ? 0.25 : viewMode === 'wire' ? 0.6 : 0.3) * alphaBase * brightness;
          ctx.beginPath();
          ctx.moveTo(projA.sx, projA.sy);
          ctx.lineTo(projB.sx, projB.sy);
          ctx.setLineDash(edge.isWaterline ? [3, 2] : []);
          ctx.strokeStyle = `rgba(${edge.r},${edge.g},${edge.bCh},${lineAlpha})`;
          ctx.lineWidth = viewMode === 'wire' ? 0.8 : 0.5;
          ctx.stroke();
        });
        ctx.setLineDash([]);
      }

      // 포인트 (back-to-front 정렬)
      if (showPoints) {
        const projected = geo.points.map((pt) => {
          const { sx, sy, sc } = project(pt.x, pt.y, pt.z, angle);
          return { sx, sy, sc, pt };
        });
        projected.sort((a, b) => a.sc - b.sc);

        projected.forEach(({ sx, sy, sc, pt }) => {
          const brightness = 0.4 + sc * 0.8;
          const ptAlpha = (viewMode === 'point' ? 0.75 : 0.5) * alphaBase * brightness;
          const ptRadius = (viewMode === 'point' ? pt.radius * 1.4 : pt.radius * 0.8) * sc;
          ctx.beginPath();
          ctx.arc(sx, sy, Math.max(0.3, ptRadius), 0, Math.PI * 2);
          ctx.fillStyle = `rgba(${pt.r},${pt.g},${pt.b},${ptAlpha})`;
          ctx.fill();
        });
      }

      // Labels (3d 모드, !isProcessing)
      if (viewMode === '3d' && !isProcessing) {
        const bowProj = project(1.0, 0, 0, angle);
        const sternProj = project(-1.0, 0, 0, angle);
        ctx.font = '8px var(--fM, monospace)';
        ctx.fillStyle = 'rgba(6,182,212,0.5)';
        ctx.fillText('선수', bowProj.sx + 4, bowProj.sy);
        ctx.fillText('선미', sternProj.sx - 20, sternProj.sy);

        ctx.fillStyle = 'rgba(34,197,94,0.7)';
        ctx.textAlign = 'center';
        ctx.fillText('84.7m', cx, H - 12);
        ctx.textAlign = 'left';
      }

      angleRef.current += 0.006;
      rafRef.current = requestAnimationFrame(render);
    };

    render();

    return () => {
      cancelAnimationFrame(rafRef.current);
    };
  }, [viewMode, isProcessing, geo]);

  return (
    <div className="absolute inset-0 flex items-center justify-center">
      <canvas
        ref={canvasRef}
        style={{ filter: isProcessing ? 'saturate(0.3) opacity(0.5)' : undefined }}
      />
      {isProcessing && (
        <div className="absolute inset-0 flex items-center justify-center">
          <div className="text-center">
            <div className="text-color-accent/40 text-caption font-mono animate-pulse">
              재구성 처리중...
            </div>
            <div className="w-24 h-0.5 bg-bg-card rounded-full mt-2 mx-auto overflow-hidden">
              <div
                className="h-full bg-[rgba(6,182,212,0.4)] rounded-full"
                style={{ width: '64%', animation: 'pulse 2s infinite' }}
              />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────
// Pollution3DModel
// ─────────────────────────────────────────────

interface PollutionPoint {
  x: number;
  y: number;
  z: number;
  r: number;
  g: number;
  b: number;
  radius: number;
}

interface PollutionEdge {
  points: Array<{ x: number; y: number; z: number }>;
  r: number;
  g: number;
  b: number;
  isDash: boolean;
}

interface PollutionGeometry {
  points: PollutionPoint[];
  edges: PollutionEdge[];
}

function buildPollutionGeometry(): PollutionGeometry {
  const rand = mulberry32(99);
  const points: PollutionPoint[] = [];
  const edges: PollutionEdge[] = [];

  // 해수면 그리드: y=0 평면, 15×15 격자 (-1.5~1.5)
  const gridCount = 15;
  const gridRange = 1.5;
  const gridStep = (gridRange * 2) / gridCount;
  for (let i = 0; i <= gridCount; i++) {
    const pos = -gridRange + i * gridStep;
    edges.push({
      points: [
        { x: -gridRange, y: 0, z: pos },
        { x: gridRange, y: 0, z: pos },
      ],
      r: 6,
      g: 182,
      b: 212,
      isDash: false,
    });
    edges.push({
      points: [
        { x: pos, y: 0, z: -gridRange },
        { x: pos, y: 0, z: gridRange },
      ],
      r: 6,
      g: 182,
      b: 212,
      isDash: false,
    });
  }

  // 오염 blob 포인트 3000개: 불규칙 타원형
  const rx = 1.0;
  const rz = 0.7;
  for (let i = 0; i < 3000; i++) {
    const angle = rand() * Math.PI * 2;
    const distR = Math.sqrt(rand()); // 균일 면적 분포
    const px = distR * rx * Math.cos(angle) * (1 + (rand() - 0.5) * 0.15);
    const pz = distR * rz * Math.sin(angle) * (1 + (rand() - 0.5) * 0.15);
    const dist = Math.sqrt((px / rx) ** 2 + (pz / rz) ** 2);
    if (dist > 1.0) continue;

    let py: number;
    let pr: number;
    let pg: number;
    let pb: number;

    if (dist < 0.3) {
      // 중심: 두꺼운 적색
      py = (rand() - 0.5) * 0.16;
      pr = 239;
      pg = 68;
      pb = 68;
    } else if (dist < 0.6) {
      // 중간: 주황
      py = (rand() - 0.5) * 0.08;
      pr = 249;
      pg = 115;
      pb = 22;
    } else {
      // 외곽: 노랑, y~0
      py = (rand() - 0.5) * 0.02;
      pr = 234;
      pg = 179;
      pb = 8;
    }

    points.push({ x: px, y: py, z: pz, r: pr, g: pg, b: pb, radius: 0.7 + rand() * 0.5 });
  }

  // 등고선 에지: 3개 동심 타원 (dist=0.3, 0.6, 0.9)
  const contours = [
    { dr: 0.3, r: 239, g: 68, b: 68 },
    { dr: 0.6, r: 249, g: 115, b: 22 },
    { dr: 0.9, r: 234, g: 179, b: 8 },
  ];
  contours.forEach(({ dr, r, g, b }) => {
    const pts: Array<{ x: number; y: number; z: number }> = [];
    const N = 48;
    for (let i = 0; i <= N; i++) {
      const a = (i / N) * Math.PI * 2;
      pts.push({ x: dr * rx * Math.cos(a), y: 0, z: dr * rz * Math.sin(a) });
    }
    edges.push({ points: pts, r, g, b, isDash: true });
  });

  // 외곽 경계 에지 (불규칙 타원)
  const outerPts: Array<{ x: number; y: number; z: number }> = [];
  const N = 64;
  for (let i = 0; i <= N; i++) {
    const a = (i / N) * Math.PI * 2;
    const noise = 1 + (Math.sin(a * 3.7) * 0.08 + Math.sin(a * 7.1) * 0.05);
    outerPts.push({ x: rx * noise * Math.cos(a), y: 0, z: rz * noise * Math.sin(a) });
  }
  edges.push({ points: outerPts, r: 239, g: 68, b: 68, isDash: false });

  // 확산 방향 화살표 에지 (ESE 방향)
  const arrowAngle = -0.3; // ESE
  const arrowLen = 1.2;
  const ax = Math.cos(arrowAngle) * arrowLen;
  const az = Math.sin(arrowAngle) * arrowLen;
  edges.push({
    points: [
      { x: 0.5, y: 0, z: 0.2 },
      { x: 0.5 + ax, y: 0, z: 0.2 + az },
    ],
    r: 249,
    g: 115,
    b: 22,
    isDash: false,
  });

  return { points, edges };
}

function Pollution3DModel({ viewMode, status }: { viewMode: string; status: string }) {
  const isProcessing = status === 'processing';
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const angleRef = useRef(0);
  const rafRef = useRef<number>(0);

  const W = 420;
  const H = 300;
  const FOV = 4.0;
  const geo = useMemo(() => buildPollutionGeometry(), []);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const dpr = window.devicePixelRatio || 1;
    canvas.width = W * dpr;
    canvas.height = H * dpr;
    canvas.style.width = `${W}px`;
    canvas.style.height = `${H}px`;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;
    ctx.scale(dpr, dpr);

    const cx = W / 2;
    const cy = H / 2 + 20;
    const scale3d = 100;

    const project = (
      px: number,
      py: number,
      pz: number,
      angle: number,
    ): { sx: number; sy: number; sc: number } => {
      const cosA = Math.cos(angle);
      const sinA = Math.sin(angle);
      const rx = px * cosA - pz * sinA;
      const rz = px * sinA + pz * cosA;
      const cosT = Math.cos(POLLUTION_TILT_X);
      const sinT = Math.sin(POLLUTION_TILT_X);
      const ry2 = py * cosT - rz * sinT;
      const rz2 = py * sinT + rz * cosT;
      const sc = FOV / (FOV + rz2 + 1.5);
      return { sx: cx + rx * scale3d * sc, sy: cy - ry2 * scale3d * sc, sc };
    };

    const render = () => {
      ctx.clearRect(0, 0, W, H);
      const angle = angleRef.current;
      const alphaBase = isProcessing ? 0.25 : 1.0;

      const showPoints = viewMode === 'point' || viewMode === '3d';
      const showWire = viewMode === 'wire' || viewMode === '3d';

      // 에지 렌더링
      if (showWire) {
        geo.edges.forEach((edge) => {
          if (edge.points.length < 2) return;
          // 그리드는 매우 얇게
          const isGrid = !edge.isDash && edge.r === 6 && edge.b === 212;
          const lineAlpha = isGrid
            ? 0.06 * alphaBase
            : edge.isDash
              ? 0.35 * alphaBase
              : 0.55 * alphaBase;

          ctx.beginPath();
          const first = project(edge.points[0].x, edge.points[0].y, edge.points[0].z, angle);
          ctx.moveTo(first.sx, first.sy);
          for (let i = 1; i < edge.points.length; i++) {
            const p = project(edge.points[i].x, edge.points[i].y, edge.points[i].z, angle);
            ctx.lineTo(p.sx, p.sy);
          }
          ctx.setLineDash(edge.isDash ? [3, 2] : []);
          ctx.strokeStyle = `rgba(${edge.r},${edge.g},${edge.b},${lineAlpha})`;
          ctx.lineWidth = isGrid ? 0.4 : 0.8;
          ctx.stroke();
        });
        ctx.setLineDash([]);
      }

      // 포인트 (back-to-front 정렬)
      if (showPoints) {
        const projected = geo.points.map((pt) => {
          const { sx, sy, sc } = project(pt.x, pt.y, pt.z, angle);
          return { sx, sy, sc, pt };
        });
        projected.sort((a, b) => a.sc - b.sc);

        projected.forEach(({ sx, sy, sc, pt }) => {
          const brightness = 0.4 + sc * 0.7;
          const ptAlpha = (viewMode === 'point' ? 0.8 : 0.55) * alphaBase * brightness;
          const ptRadius = (viewMode === 'point' ? pt.radius * 1.3 : pt.radius * 0.9) * sc;
          ctx.beginPath();
          ctx.arc(sx, sy, Math.max(0.3, ptRadius), 0, Math.PI * 2);
          ctx.fillStyle = `rgba(${pt.r},${pt.g},${pt.b},${ptAlpha})`;
          ctx.fill();
        });
      }

      // Labels (3d 모드, !isProcessing)
      if (viewMode === '3d' && !isProcessing) {
        const p30 = project(0, 0.08, 0, angle);
        const p60 = project(0, 0.04, 0.45, angle);
        const p90 = project(0, 0, 0.8, angle);
        ctx.font = '7px var(--fM, monospace)';
        ctx.fillStyle = 'rgba(239,68,68,0.75)';
        ctx.fillText('3.2mm', p30.sx + 3, p30.sy);
        ctx.fillStyle = 'rgba(249,115,22,0.65)';
        ctx.fillText('1.5mm', p60.sx + 3, p60.sy);
        ctx.fillStyle = 'rgba(234,179,8,0.6)';
        ctx.fillText('0.3mm', p90.sx + 3, p90.sy);

        ctx.fillStyle = 'rgba(34,197,94,0.7)';
        ctx.textAlign = 'center';
        ctx.fillText('1.24 km', cx, H - 10);
        ctx.textAlign = 'left';

        ctx.fillStyle = 'rgba(249,115,22,0.6)';
        ctx.fillText('ESE 0.3km/h', cx + 55, cy - 30);
      }

      angleRef.current += 0.006;
      rafRef.current = requestAnimationFrame(render);
    };

    render();

    return () => {
      cancelAnimationFrame(rafRef.current);
    };
  }, [viewMode, isProcessing, geo]);

  return (
    <div className="absolute inset-0 flex items-center justify-center">
      <canvas
        ref={canvasRef}
        style={{ filter: isProcessing ? 'saturate(0.3) opacity(0.5)' : undefined }}
      />

      {viewMode === '3d' && !isProcessing && (
        <div
          className="absolute bottom-2 right-2 flex items-center gap-1"
          style={{ fontSize: '8px', color: 'var(--fg-disabled)', fontFamily: 'var(--font-mono)' }}
        >
          <span>0mm</span>
          <div
            style={{
              width: '60px',
              height: '4px',
              borderRadius: '2px',
              background:
                'linear-gradient(90deg, rgba(234,179,8,0.6), rgba(249,115,22,0.7), rgba(239,68,68,0.8))',
            }}
          />
          <span>3.2mm</span>
        </div>
      )}

      {isProcessing && (
        <div className="absolute inset-0 flex items-center justify-center">
          <div className="text-center">
            <div className="text-color-danger/40 text-caption font-mono animate-pulse">
              재구성 처리중...
            </div>
            <div className="w-24 h-0.5 bg-bg-card rounded-full mt-2 mx-auto overflow-hidden">
              <div
                className="h-full bg-[rgba(239,68,68,0.4)] rounded-full"
                style={{ width: '52%', animation: 'pulse 2s infinite' }}
              />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

export function SensorAnalysis() {
  const [subTab, setSubTab] = useState<'vessel' | 'pollution'>('vessel');
  const [viewMode, setViewMode] = useState('3d');
  const [selectedItem, setSelectedItem] = useState<ReconItem>(reconItems[1]);

  const filteredItems = reconItems.filter(
    (r) => r.type === (subTab === 'vessel' ? 'vessel' : 'pollution'),
  );

  return (
    <div
      className="flex h-full overflow-hidden"
      style={{ margin: '-20px -24px', height: 'calc(100% + 40px)' }}
    >
      {/* Left Panel */}
      <div className="w-[280px] bg-bg-surface border-r border-stroke flex flex-col overflow-auto">
        {/* 3D Reconstruction List */}
        <div className="p-2.5 px-3 border-b border-stroke">
          <div className="text-caption font-bold text-fg-disabled mb-1.5 uppercase tracking-wider">
            📋 3D 재구성 완료 목록
          </div>
          <div className="flex gap-1 mb-2">
            <button
              onClick={() => setSubTab('vessel')}
              className={`flex-1 py-1.5 text-center text-caption font-semibold rounded cursor-pointer border transition-colors font-korean ${
                subTab === 'vessel'
                  ? 'text-color-accent bg-[rgba(6,182,212,0.08)] border-[rgba(6,182,212,0.2)]'
                  : 'text-fg-disabled bg-bg-base border-stroke'
              }`}
            >
              🚢 선박
            </button>
            <button
              onClick={() => setSubTab('pollution')}
              className={`flex-1 py-1.5 text-center text-caption font-semibold rounded cursor-pointer border transition-colors font-korean ${
                subTab === 'pollution'
                  ? 'text-color-accent bg-[rgba(6,182,212,0.08)] border-[rgba(6,182,212,0.2)]'
                  : 'text-fg-disabled bg-bg-base border-stroke'
              }`}
            >
              🛢️ 오염원
            </button>
          </div>
          <div className="flex flex-col gap-1">
            {filteredItems.map((item) => (
              <div
                key={item.id}
                onClick={() => setSelectedItem(item)}
                className={`flex items-center gap-2 px-2 py-2 rounded-sm cursor-pointer transition-colors border ${
                  selectedItem.id === item.id
                    ? 'bg-[rgba(6,182,212,0.08)] border-[rgba(6,182,212,0.2)]'
                    : 'border-transparent hover:bg-white/[0.02]'
                }`}
              >
                <div className="flex-1 min-w-0">
                  <div className="text-caption font-bold text-fg font-korean">{item.name}</div>
                  <div className="text-caption text-fg-disabled font-mono">
                    {item.id} · {item.points} pts
                  </div>
                </div>
                <span
                  className={`text-caption font-semibold ${item.status === 'complete' ? 'text-color-success' : 'text-color-warning'}`}
                >
                  {item.status === 'complete' ? '완료' : '처리중'}
                </span>
              </div>
            ))}
          </div>
        </div>

        {/* Source Images */}
        <div className="p-2.5 px-3 flex-1 min-h-0 flex flex-col">
          <div className="text-caption font-bold text-fg-disabled mb-1.5 uppercase tracking-wider">
            📹 촬영 원본
          </div>
          <div className="grid grid-cols-2 gap-1">
            {[
              { label: 'D-01 정면', sensor: '광학', color: 'text-fg-sub' },
              { label: 'D-02 좌현', sensor: 'IR', color: 'text-fg-sub' },
              { label: 'D-03 우현', sensor: '광학', color: 'text-fg-sub' },
              { label: 'D-02 상부', sensor: 'IR', color: 'text-fg-sub' },
            ].map((src, i) => (
              <div
                key={i}
                className="relative rounded-sm bg-bg-base border border-stroke overflow-hidden aspect-square"
              >
                <div
                  className="absolute inset-0 flex items-center justify-center"
                  style={{ background: 'var(--bg-base)' }}
                >
                  <div className="text-fg-disabled/10 text-caption font-mono">
                    {src.label.split(' ')[0]}
                  </div>
                </div>
                <div className="absolute bottom-0 left-0 right-0 bg-black/60 px-1.5 py-1 flex justify-between text-caption text-fg-disabled font-korean">
                  <span>{src.label}</span>
                  <span className={src.color}>{src.sensor}</span>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Center Panel - 3D Canvas */}
      <div className="flex-1 relative bg-bg-base border-x border-stroke flex items-center justify-center overflow-hidden">
        {/* Simulated 3D viewport */}
        <div
          className="absolute inset-0"
          style={{ background: 'radial-gradient(ellipse at 50% 50%, #0c1a2e, #060c18)' }}
        >
          {/* Grid floor */}
          <div
            className="absolute inset-0 opacity-[0.06]"
            style={{
              backgroundImage:
                'linear-gradient(rgba(6,182,212,0.5) 1px, transparent 1px), linear-gradient(90deg, rgba(6,182,212,0.5) 1px, transparent 1px)',
              backgroundSize: '40px 40px',
              transform: 'perspective(500px) rotateX(55deg)',
              transformOrigin: 'center 80%',
            }}
          />

          {/* 3D Model Visualization */}
          {selectedItem.type === 'vessel' ? (
            <Vessel3DModel viewMode={viewMode} status={selectedItem.status} />
          ) : (
            <Pollution3DModel viewMode={viewMode} status={selectedItem.status} />
          )}

          {/* Axis indicator */}
          <div
            className="absolute bottom-16 left-4"
            style={{ fontSize: '9px', fontFamily: 'var(--font-mono)' }}
          >
            <div style={{ color: 'var(--color-danger)' }}>X →</div>
            <div className="text-green-500">Y ↑</div>
            <div className="text-blue-500">Z ⊙</div>
          </div>
        </div>

        {/* Title */}
        <div className="absolute top-3 left-3 z-[2]">
          <div className="text-caption font-bold text-fg-disabled uppercase tracking-wider">
            3D Vessel Analysis
          </div>
          <div className="text-title-4 font-bold text-color-accent my-1 font-korean">
            {selectedItem.name} 정밀분석
          </div>
          <div className="text-caption text-fg-disabled font-mono">
            34.58°N, 129.30°E · {selectedItem.status === 'complete' ? '재구성 완료' : '처리중'}
          </div>
        </div>

        {/* View Mode Buttons */}
        <div className="absolute top-3 right-3 flex gap-1 z-[2]">
          {[
            { id: '3d', label: '3D모델' },
            { id: 'point', label: '포인트클라우드' },
            { id: 'wire', label: '와이어프레임' },
          ].map((m) => (
            <button
              key={m.id}
              onClick={() => setViewMode(m.id)}
              className={`px-2.5 py-1.5 text-caption font-semibold rounded-sm cursor-pointer border font-korean transition-colors ${
                viewMode === m.id
                  ? 'bg-[rgba(6,182,212,0.2)] border-[rgba(6,182,212,0.5)] text-color-accent'
                  : 'bg-black/40 border-[rgba(6,182,212,0.2)] text-fg-disabled hover:bg-black/60 hover:border-[rgba(6,182,212,0.4)]'
              }`}
            >
              {m.label}
            </button>
          ))}
        </div>

        {/* Bottom Stats */}
        <div
          className="absolute bottom-3 left-1/2 -translate-x-1/2 flex gap-3 bg-black/50 backdrop-blur-lg px-4 py-2 rounded-md border z-[2]"
          style={{ borderColor: 'var(--stroke-default)' }}
        >
          {[
            { value: selectedItem.points, label: '포인트' },
            { value: selectedItem.polygons, label: '폴리곤' },
            { value: '3', label: '시점' },
            { value: selectedItem.coverage, label: '커버리지' },
            { value: '0.023m', label: 'RMS오차' },
          ].map((s, i) => (
            <div key={i} className="text-center">
              <div className="font-mono font-bold text-body-2 text-color-accent">{s.value}</div>
              <div className="text-caption text-fg-disabled mt-0.5 font-korean">{s.label}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Right Panel - Analysis Details */}
      <div className="w-[270px] bg-bg-surface border-l border-stroke flex flex-col overflow-auto">
        {/* Ship/Pollution Info */}
        <div className="p-2.5 px-3 border-b border-stroke">
          <div className="text-caption font-bold text-fg-disabled mb-2 uppercase tracking-wider">
            📊 분석 정보
          </div>
          <div className="flex flex-col gap-1.5 text-caption">
            {(selectedItem.type === 'vessel'
              ? [
                  ['대상', selectedItem.name],
                  ['선종 추정', '일반화물선 (추정)'],
                  ['길이', '약 85m'],
                  ['폭', '약 14m'],
                  ['AIS 상태', 'OFF (미식별)'],
                  ['최초 탐지', '2026-01-18 14:20'],
                  ['촬영 시점', '3 시점 (정면/좌현/우현)'],
                  ['센서', '광학 4K + IR 열화상'],
                ]
              : [
                  ['대상', selectedItem.name],
                  ['유형', '유류 오염'],
                  ['추정 면적', '0.42 km²'],
                  ['추정 유출량', '12.6 kL'],
                  ['유종', 'B-C유 (추정)'],
                  ['최초 탐지', '2026-01-18 13:50'],
                  ['확산 속도', '0.3 km/h (ESE 방향)'],
                ]
            ).map(([k, v], i) => (
              <div key={i} className="flex justify-between items-start">
                <span className="text-fg-disabled font-korean">{k}</span>
                <span className="font-mono font-semibold text-fg text-right ml-2">{v}</span>
              </div>
            ))}
          </div>
        </div>

        {/* AI Detection Results */}
        <div className="p-2.5 px-3 border-b border-stroke">
          <div className="text-caption font-bold text-fg-disabled mb-2 uppercase tracking-wider">
            🤖 AI 탐지 결과
          </div>
          <div className="flex flex-col gap-1">
            {(selectedItem.type === 'vessel'
              ? [
                  { label: '선박 식별', confidence: 94, color: 'bg-color-success' },
                  { label: '선종 분류', confidence: 78, color: 'bg-color-success' },
                  { label: '손상 감지', confidence: 45, color: 'bg-color-success' },
                  { label: '화물 분석', confidence: 62, color: 'bg-color-success' },
                ]
              : [
                  { label: '유막 탐지', confidence: 97, color: 'bg-color-success' },
                  { label: '유종 분류', confidence: 85, color: 'bg-color-success' },
                  { label: '두께 추정', confidence: 72, color: 'bg-color-success' },
                  { label: '확산 예측', confidence: 68, color: 'bg-color-success' },
                ]
            ).map((r, i) => (
              <div key={i}>
                <div className="flex justify-between text-caption mb-0.5">
                  <span className="text-fg-disabled font-korean">{r.label}</span>
                  <span className="font-mono font-semibold text-fg">{r.confidence}%</span>
                </div>
                <div className="w-full h-1 bg-bg-base rounded-full overflow-hidden">
                  <div
                    className={`h-full rounded-full ${r.color}`}
                    style={{ width: `${r.confidence}%` }}
                  />
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Comparison / Measurements */}
        <div className="p-2.5 px-3 border-b border-stroke">
          <div className="text-caption font-bold text-fg-disabled mb-2 uppercase tracking-wider">
            📐 3D 측정값
          </div>
          <div className="flex flex-col gap-1 text-caption">
            {(selectedItem.type === 'vessel'
              ? [
                  ['전장 (LOA)', '84.7 m'],
                  ['형폭 (Breadth)', '14.2 m'],
                  ['건현 (Freeboard)', '3.8 m'],
                  ['흘수 (Draft)', '5.6 m (추정)'],
                  ['마스트 높이', '22.3 m'],
                ]
              : [
                  ['유막 면적', '0.42 km²'],
                  ['최대 길이', '1.24 km'],
                  ['최대 폭', '0.68 km'],
                  ['평균 두께', '0.8 mm'],
                  ['최대 두께', '3.2 mm'],
                ]
            ).map(([k, v], i) => (
              <div key={i} className="flex justify-between px-2 py-1 bg-bg-base rounded">
                <span className="text-fg-disabled font-korean">{k}</span>
                <span className="font-mono font-semibold text-fg">{v}</span>
              </div>
            ))}
          </div>
        </div>

        {/* Action Buttons */}
        <div className="p-2.5 px-3">
          <button
            className="w-full py-2.5 rounded-sm text-label-2 font-semibold font-korean text-color-accent border cursor-pointer mb-2 transition-colors"
            style={{
              border: '1px solid rgba(6,182,212,.3)',
              background: 'rgba(6,182,212,.08)',
            }}
          >
            📊 상세 보고서 생성
          </button>
          <button className="w-full py-2 border border-stroke bg-bg-card text-fg-sub rounded-sm text-label-2 font-semibold font-korean cursor-pointer hover:bg-bg-surface-hover transition-colors">
            📥 3D 모델 다운로드
          </button>
        </div>
      </div>
    </div>
  );
}
