"use client";

import { useState } from "react";
import { cn } from "@/lib/utils";
import type { DirectionAnalysis, FengShuiResult } from "@/lib/feng-shui/bat-trach";

/**
 * Bagua wheel — interactive SVG that rotates the 8-direction Bát Trạch
 * mapping to match the user's house compass heading.
 *
 * Why rotate: real houses don't always face true North. If a house faces
 * 90° (Đông), the door's Bát Trạch fortune should be read at the position
 * pointing Đông, not Bắc. The wheel snaps to 45° increments so each slice
 * (octant) clearly shows which direction it represents at the rotated
 * orientation.
 *
 * The component is intentionally controlled by URL state: parent passes
 * the initial heading, but the slider mutates a local `heading` so the
 * user can drag without page reload. Because the underlying fortune
 * data does NOT depend on heading (only the rendering orientation does),
 * we can compute everything client-side.
 */
export function BaguaWheel({
  result,
  initialHeading = 0,
}: {
  result: FengShuiResult;
  /** Compass heading the house's MAIN DOOR faces, in degrees (0=Bắc, 90=Đông, 180=Nam, 270=Tây). */
  initialHeading?: number;
}) {
  const [heading, setHeading] = useState(initialHeading);

  const size = 360;
  const r = size / 2;
  const innerR = 70;
  const cx = r;
  const cy = r;

  // Octant order matches the cardinal/intercardinal sequence starting at
  // Bắc (top, 0°) and going clockwise: B → ĐB → Đ → ĐN → N → TN → T → TB.
  const ORDER: Array<{ key: string; label: string; short: string }> = [
    { key: "Bắc", label: "Bắc", short: "B" },
    { key: "Đông Bắc", label: "Đông Bắc", short: "ĐB" },
    { key: "Đông", label: "Đông", short: "Đ" },
    { key: "Đông Nam", label: "Đông Nam", short: "ĐN" },
    { key: "Nam", label: "Nam", short: "N" },
    { key: "Tây Nam", label: "Tây Nam", short: "TN" },
    { key: "Tây", label: "Tây", short: "T" },
    { key: "Tây Bắc", label: "Tây Bắc", short: "TB" },
  ];

  const ringSlices = ORDER.map((o, i) => {
    const dir = result.allDirections.find((d) => d.direction === o.key)!;
    return { ...o, dir, baseAngle: i * 45 };
  });

  return (
    <div className="border-stroke-default bg-bg-elevated/40 rounded-2xl border p-5 lg:p-7">
      <div className="mb-4 flex flex-wrap items-baseline justify-between gap-2">
        <h3 className="font-display text-lg font-semibold lg:text-xl">
          La bàn Bát Trạch · Bánh xe bát quái
        </h3>
        <span className="text-ink-muted text-xs">
          Cung mệnh <span className="text-brand-gold font-semibold">{result.cungMenh}</span> ·{" "}
          {result.group}
        </span>
      </div>

      <div className="grid items-start gap-6 md:grid-cols-[auto_1fr]">
        {/* SVG wheel */}
        <div className="mx-auto" style={{ width: size, maxWidth: "100%" }}>
          <svg
            viewBox={`0 0 ${size} ${size}`}
            className="block w-full"
            role="img"
            aria-label={`La bàn 8 hướng cho cung ${result.cungMenh}`}
          >
            <defs>
              <radialGradient id="bagua-bg" cx="50%" cy="50%" r="50%">
                <stop offset="0%" stopColor="rgba(216,168,90,0.10)" />
                <stop offset="100%" stopColor="rgba(216,168,90,0.02)" />
              </radialGradient>
            </defs>

            {/* Outer rotating ring */}
            <g transform={`rotate(${heading} ${cx} ${cy})`}>
              {ringSlices.map((s) => {
                const startAngle = s.baseAngle - 22.5;
                const endAngle = s.baseAngle + 22.5;
                const path = arcPath(cx, cy, r - 4, innerR, startAngle, endAngle);
                const labelPos = polar(cx, cy, (r + innerR) / 2, s.baseAngle);
                return (
                  <g key={s.key}>
                    <path
                      d={path}
                      fill={s.dir.isAuspicious ? "rgba(16,185,129,0.18)" : "rgba(244,63,94,0.18)"}
                      stroke={s.dir.isAuspicious ? "rgba(16,185,129,0.55)" : "rgba(244,63,94,0.55)"}
                      strokeWidth={1}
                    />
                    {/* Counter-rotate the label so text stays upright at any wheel rotation. */}
                    <g transform={`rotate(${-heading} ${labelPos.x} ${labelPos.y})`}>
                      <text
                        x={labelPos.x}
                        y={labelPos.y - 6}
                        textAnchor="middle"
                        className="fill-ink-primary"
                        style={{ fontSize: 14, fontWeight: 600 }}
                      >
                        {s.label}
                      </text>
                      <text
                        x={labelPos.x}
                        y={labelPos.y + 12}
                        textAnchor="middle"
                        className={s.dir.isAuspicious ? "fill-emerald-300" : "fill-rose-300"}
                        style={{ fontSize: 11 }}
                      >
                        {s.dir.fortune}
                      </text>
                    </g>
                  </g>
                );
              })}
            </g>

            {/* Center medallion (does NOT rotate — anchored to native cardinal). */}
            <circle
              cx={cx}
              cy={cy}
              r={innerR - 4}
              fill="url(#bagua-bg)"
              stroke="rgba(216,168,90,0.5)"
            />
            <text
              x={cx}
              y={cy - 8}
              textAnchor="middle"
              className="fill-brand-gold"
              style={{ fontSize: 13, fontWeight: 700, letterSpacing: "0.18em" }}
            >
              {result.cungMenh.toUpperCase()}
            </text>
            <text
              x={cx}
              y={cy + 12}
              textAnchor="middle"
              className="fill-ink-muted"
              style={{ fontSize: 11 }}
            >
              hành {result.element}
            </text>

            {/* Door arrow — fixed pointing UP, indicates user faces THIS direction. */}
            <g transform={`translate(${cx} ${cy})`}>
              <path
                d="M 0 -150 L -10 -130 L 10 -130 Z"
                fill="rgba(216,168,90,0.95)"
                stroke="rgba(0,0,0,0.4)"
              />
              <line
                x1={0}
                y1={-130}
                x2={0}
                y2={-100}
                stroke="rgba(216,168,90,0.7)"
                strokeWidth={2}
                strokeDasharray="3 3"
              />
            </g>
          </svg>
        </div>

        {/* Heading control */}
        <div>
          <label className="block">
            <span className="text-ink-muted block text-xs font-semibold tracking-wide uppercase">
              Hướng cửa chính
            </span>
            <div className="mt-2 flex flex-wrap items-center gap-3">
              <input
                type="range"
                min={0}
                max={360}
                step={45}
                value={heading}
                onChange={(e) => setHeading(parseInt(e.target.value, 10))}
                className="accent-brand-gold w-48"
                aria-label="Hướng cửa chính (độ)"
              />
              <span className="font-display text-brand-gold w-16 text-center text-sm font-semibold">
                {heading}°
              </span>
              <select
                value={heading}
                onChange={(e) => setHeading(parseInt(e.target.value, 10))}
                className="bg-bg-inset border-stroke-default text-ink-primary focus:border-brand-gold rounded-md border px-3 py-1.5 text-sm focus:outline-none"
              >
                <option value={0}>Bắc (0°)</option>
                <option value={45}>Đông Bắc (45°)</option>
                <option value={90}>Đông (90°)</option>
                <option value={135}>Đông Nam (135°)</option>
                <option value={180}>Nam (180°)</option>
                <option value={225}>Tây Nam (225°)</option>
                <option value={270}>Tây (270°)</option>
                <option value={315}>Tây Bắc (315°)</option>
              </select>
            </div>
          </label>

          <p className="text-ink-secondary mt-3 text-xs leading-relaxed">
            Mũi tên vàng = hướng cửa chính nhà bạn quay ra. Khi xoay, các múi bát quái xoay theo,
            nhưng nhãn vẫn đứng để bạn dễ đọc cát/hung tại vị trí thực tế.
          </p>

          <CompassLegend
            bestDirection={result.bestDirection}
            worstDirection={result.worstDirection}
          />
        </div>
      </div>
    </div>
  );
}

function CompassLegend({
  bestDirection,
  worstDirection,
}: {
  bestDirection: DirectionAnalysis;
  worstDirection: DirectionAnalysis;
}) {
  return (
    <div className="border-stroke-subtle/60 mt-4 rounded-lg border p-3 text-xs">
      <div className="mb-1 flex items-center gap-2">
        <span className="inline-block h-3 w-3 rounded-sm bg-emerald-500/60" />
        <span className="text-ink-secondary">
          Hướng cát mạnh nhất —{" "}
          <span className="font-medium text-emerald-300">{bestDirection.direction}</span> ·{" "}
          {bestDirection.fortune}
        </span>
      </div>
      <div className="flex items-center gap-2">
        <span className="inline-block h-3 w-3 rounded-sm bg-rose-500/60" />
        <span className="text-ink-secondary">
          Hướng hung nặng nhất —{" "}
          <span className="font-medium text-rose-300">{worstDirection.direction}</span> ·{" "}
          {worstDirection.fortune}
        </span>
      </div>
    </div>
  );
}

// ---------- SVG geometry helpers ----------

function polar(cx: number, cy: number, radius: number, angleDeg: number) {
  // Convention: 0° = top (north). +clockwise.
  const rad = ((angleDeg - 90) * Math.PI) / 180;
  return { x: cx + radius * Math.cos(rad), y: cy + radius * Math.sin(rad) };
}

function arcPath(
  cx: number,
  cy: number,
  outerR: number,
  innerR: number,
  startDeg: number,
  endDeg: number
): string {
  const p0 = polar(cx, cy, outerR, startDeg);
  const p1 = polar(cx, cy, outerR, endDeg);
  const p2 = polar(cx, cy, innerR, endDeg);
  const p3 = polar(cx, cy, innerR, startDeg);
  const largeArc = endDeg - startDeg > 180 ? 1 : 0;
  return [
    `M ${p0.x} ${p0.y}`,
    `A ${outerR} ${outerR} 0 ${largeArc} 1 ${p1.x} ${p1.y}`,
    `L ${p2.x} ${p2.y}`,
    `A ${innerR} ${innerR} 0 ${largeArc} 0 ${p3.x} ${p3.y}`,
    "Z",
  ].join(" ");
}
