import { keyframes, styled } from "@mui/material/styles";
import Box from "@mui/material/Box";
import { useReducedMotion } from "framer-motion";

/**
 * Odin's animated brand mark: an AI "spark" (Odin) with a data node orbiting a
 * ring — the assistant at the centre of the business system, in BOHA red. The
 * spark slow-rotates and breathes; the node orbits. In the "thinking" state
 * everything speeds up and the tile glows. Honours prefers-reduced-motion.
 *
 * The animations live in a `styled("svg")` (not inline style): Emotion only
 * injects the @keyframes rule when the keyframes object is used inside
 * sx/css/styled, and the child selectors keep the SVG elements plain/typed.
 */
const breathe = keyframes`
  0%, 100% { transform: scale(0.9); opacity: 0.9; }
  50% { transform: scale(1.08); opacity: 1; }
`;
const spin = keyframes`
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
`;
// Reduce-motion safe: opacity only (no transforms / no travel).
const glow = keyframes`
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
`;

const Glyph = styled("svg", {
  shouldForwardProp: (p) => p !== "thinking" && p !== "reduce",
})<{ thinking: boolean; reduce: boolean }>(({ thinking, reduce }) => ({
  // !important so an ancestor `& svg { width }` rule (e.g. SidebarNav forces
  // 18px) can't override the mark's own sizing — `size` stays authoritative.
  width: "70% !important",
  height: "70% !important",
  overflow: "visible",
  display: "block",
  ...(reduce
    ? {
        // Reduce-motion: keep a calm opacity glow (no spin/orbit/travel). The
        // `!important` + class specificity intentionally overrides the app-wide
        // reduced-motion reset in GlobalStyles for this one small mark, since an
        // opacity pulse is accessibility-safe (it isn't vestibular motion).
        "& .odin-spark": {
          animation: `${glow} ${thinking ? "1.1s" : "3s"} ease-in-out infinite !important`,
        },
      }
    : {
        "& .odin-orbit": {
          transformBox: "view-box",
          transformOrigin: "12px 12px",
          animation: `${spin} ${thinking ? "1.6s" : "5.5s"} linear infinite`,
        },
        "& .odin-spin": {
          transformBox: "view-box",
          transformOrigin: "12px 12px",
          animation: `${spin} ${thinking ? "4s" : "11s"} linear infinite`,
        },
        "& .odin-spark": {
          transformBox: "fill-box",
          transformOrigin: "center",
          animation: `${breathe} ${thinking ? "1s" : "2.8s"} ease-in-out infinite`,
        },
      }),
}));

export interface OdinMarkProps {
  size?: number;
  state?: "idle" | "thinking";
}

export default function OdinMark({ size = 28, state = "idle" }: OdinMarkProps) {
  const reduce = !!useReducedMotion();
  const thinking = state === "thinking";

  return (
    <Box
      sx={(t) => ({
        width: size,
        height: size,
        borderRadius: "32%",
        flexShrink: 0,
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
        background: `linear-gradient(135deg, ${t.vars!.palette.primary.main}, ${t.vars!.palette.primary.dark})`,
        boxShadow: thinking
          ? `0 0 ${Math.round(size * 0.5)}px 0 rgba(${t.vars!.palette.primary.mainChannel} / 0.55)`
          : "none",
        transition: "box-shadow 0.3s ease",
      })}
    >
      <Glyph viewBox="0 0 24 24" thinking={thinking} reduce={reduce}>
        {/* orbit ring */}
        <circle
          cx="12"
          cy="12"
          r="9.2"
          fill="none"
          stroke="#fff"
          strokeOpacity="0.28"
          strokeWidth="1"
        />
        {/* orbiting data node */}
        <g className="odin-orbit">
          <circle cx="12" cy="2.8" r="1.4" fill="#fff" />
        </g>
        {/* spark — group slow-rotates, the star breathes about its own centre */}
        <g className="odin-spin">
          <path
            className="odin-spark"
            d="M12 4.5 C12.5 9, 13 9.5, 17.5 12 C13 14.5, 12.5 15, 12 19.5 C11.5 15, 11 14.5, 6.5 12 C11 9.5, 11.5 9, 12 4.5 Z"
            fill="#fff"
          />
        </g>
      </Glyph>
    </Box>
  );
}
