import React from "react";
import Svg, { Circle, G, Path, Text as SvgText } from "react-native-svg";
import type { ManeuverType } from "../../modules/mapmap-react-native/src/MapmapNav.types";
import { theme } from "../theme";

export type ManeuverIconProps = {
  type: ManeuverType;
  /** Square icon side length. Default 32. */
  size?: number;
  /** Stroke/fill colour; default ink (use textOnSignal on a signal/ink banner bg). */
  color?: string;
  /** Shown inside the roundabout ring when type === "roundabout". */
  roundaboutExit?: number;
};

/** Rotation (degrees, clockwise, 0 = up) for the directional arrow types. */
const ROTATION_BY_TYPE: Partial<Record<ManeuverType, number>> = {
  straight: 0,
  "slight-right": 30,
  "turn-right": 90,
  "sharp-right": 135,
  "slight-left": -30,
  "turn-left": -90,
  "sharp-left": -135,
};

/** A single hand-drawn arrow, tip pointing up, in a 24x24 viewBox. */
const ARROW_PATH = "M12 3 L19 12 L14.5 12 L14.5 21 L9.5 21 L9.5 12 L5 12 Z";

function DirectionalArrow({
  type,
  color,
}: {
  type: ManeuverType;
  color: string;
}): React.JSX.Element {
  const rotation = ROTATION_BY_TYPE[type] ?? 0;
  return (
    <G rotation={rotation} origin="12,12">
      <Path d={ARROW_PATH} fill={color} />
    </G>
  );
}

function DepartIcon({ color }: { color: string }): React.JSX.Element {
  return (
    <G>
      <Circle cx={12} cy={17} r={3} fill={color} />
      <Path d="M12 3 L17 11 L13 11 L13 14.2 L11 14.2 L11 11 L7 11 Z" fill={color} />
    </G>
  );
}

function ArriveIcon({ color }: { color: string }): React.JSX.Element {
  return (
    <G>
      <Path d="M7 3 H8.6 V21 H7 Z" fill={color} />
      <Path d="M8.6 4 L18 7.5 L8.6 11 Z" fill={color} />
    </G>
  );
}

function UTurnIcon({ color }: { color: string }): React.JSX.Element {
  return (
    <Path
      d="M9 21 V11 A5 5 0 0 1 19 11 V13 L23 10 L19 7 V9 A7 7 0 0 0 7 11 V21 Z"
      fill={color}
    />
  );
}

/** Straight arrow with a branch line peeling away — merge / on-ramp / off-ramp. */
function BranchArrow({
  color,
  branchSide,
  branchFromBelow,
}: {
  color: string;
  branchSide: "left" | "right";
  branchFromBelow: boolean;
}): React.JSX.Element {
  const mirror = branchSide === "left" ? -1 : 1;
  const branchPath = branchFromBelow
    ? `M${12 + mirror * 3} 21 L${12 + mirror * 8} 14`
    : `M${12 + mirror * 8} 4 L${12 + mirror * 3} 12`;

  return (
    <G>
      <Path
        d={branchPath}
        stroke={color}
        strokeWidth={2.4}
        strokeLinecap="round"
        fill="none"
      />
      <Path d={ARROW_PATH} fill={color} />
    </G>
  );
}

function ForkIcon({
  color,
  side,
}: {
  color: string;
  side: "left" | "right";
}): React.JSX.Element {
  const mirror = side === "left" ? -1 : 1;
  return (
    <G>
      <Path
        d={`M12 21 L12 13 L${12 - mirror * 6} 4`}
        stroke={color}
        strokeWidth={2}
        strokeLinecap="round"
        fill="none"
        opacity={0.35}
      />
      <Path
        d={`M12 21 L12 13 L${12 + mirror * 6} 4`}
        stroke={color}
        strokeWidth={2.6}
        strokeLinecap="round"
        fill="none"
      />
    </G>
  );
}

function RoundaboutIcon({
  color,
  exit,
}: {
  color: string;
  exit?: number;
}): React.JSX.Element {
  return (
    <G>
      <Circle
        cx={12}
        cy={12}
        r={7}
        stroke={color}
        strokeWidth={2}
        fill="none"
      />
      <Path
        d="M12 5 L15 8 L12 8 Z"
        fill={color}
        transform="rotate(45 12 12)"
      />
      {typeof exit === "number" ? (
        <SvgText
          x={12}
          y={15.5}
          fontSize={9}
          fontWeight="700"
          fill={color}
          textAnchor="middle"
        >
          {exit}
        </SvgText>
      ) : null}
    </G>
  );
}

/** Hand-drawn turn-by-turn manoeuvre glyph — banner content per S7. */
export function ManeuverIcon({
  type,
  size = 32,
  color = theme.textPrimary,
  roundaboutExit,
}: ManeuverIconProps): React.JSX.Element {
  return (
    <Svg
      width={size}
      height={size}
      viewBox="0 0 24 24"
      accessibilityLabel={`${type} manoeuvre`}
    >
      {renderGlyph(type, color, roundaboutExit)}
    </Svg>
  );
}

function renderGlyph(
  type: ManeuverType,
  color: string,
  roundaboutExit?: number
): React.JSX.Element {
  switch (type) {
    case "depart":
      return <DepartIcon color={color} />;
    case "arrive":
      return <ArriveIcon color={color} />;
    case "uturn":
      return <UTurnIcon color={color} />;
    case "roundabout":
      return <RoundaboutIcon color={color} exit={roundaboutExit} />;
    case "merge":
      return <BranchArrow color={color} branchSide="left" branchFromBelow />;
    case "on-ramp":
      return <BranchArrow color={color} branchSide="right" branchFromBelow />;
    case "off-ramp":
      return (
        <BranchArrow color={color} branchSide="right" branchFromBelow={false} />
      );
    case "fork-left":
      return <ForkIcon color={color} side="left" />;
    case "fork-right":
      return <ForkIcon color={color} side="right" />;
    case "straight":
    case "slight-left":
    case "slight-right":
    case "turn-left":
    case "turn-right":
    case "sharp-left":
    case "sharp-right":
      return <DirectionalArrow type={type} color={color} />;
    default: {
      const _exhaustive: never = type;
      return _exhaustive;
    }
  }
}
