import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Chip from "@mui/material/Chip";
import { motion, useReducedMotion, type Variants } from "framer-motion";
import type { ChatTurn } from "./types";
import OdinMark from "./OdinMark";

const MotionBox = motion.create(Box);

// Staggered hero entrance (skipped under prefers-reduced-motion).
const heroContainer: Variants = {
  hidden: {},
  show: { transition: { staggerChildren: 0.12, delayChildren: 0.06 } },
};
const heroItem: Variants = {
  hidden: { opacity: 0, y: 14 },
  show: {
    opacity: 1,
    y: 0,
    transition: { duration: 0.55, ease: [0.16, 1, 0.3, 1] },
  },
};

interface OdinThreadProps {
  turns: ChatTurn[];
  busy: boolean;
  loading: boolean;
  greetingPhrase?: string;
  userName?: string;
  threadRef: React.RefObject<HTMLDivElement | null>;
}

/** Small Odin avatar shown to the left of assistant bubbles. */
function OdinAvatar({ size = 28 }: { size?: number }) {
  return (
    <Box
      sx={{
        width: size,
        height: size,
        borderRadius: "50%",
        bgcolor: "primary.main",
        color: "common.white",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        fontWeight: 700,
        fontSize: size * 0.5,
        flexShrink: 0,
      }}
    >
      O
    </Box>
  );
}

export default function OdinThread({
  turns,
  busy,
  loading,
  greetingPhrase,
  userName,
  threadRef,
}: OdinThreadProps) {
  const reduce = useReducedMotion();
  const containerMotion = reduce
    ? {}
    : { variants: heroContainer, initial: "hidden", animate: "show" };
  const itemMotion = reduce ? {} : { variants: heroItem };
  return (
    <Box
      ref={threadRef}
      sx={{
        flex: 1,
        minHeight: 0,
        overflowY: "auto",
        display: "flex",
        flexDirection: "column",
        gap: 1.5,
        p: 2,
        bgcolor: "action.hover",
        borderRadius: 2,
      }}
    >
      {/* Loading state — history is being fetched */}
      {loading && (
        <Box
          sx={{
            flex: 1,
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
          }}
        >
          <Typography variant="body2" sx={{ color: "text.secondary" }}>
            Načítám…
          </Typography>
        </Box>
      )}

      {/* Empty state */}
      {turns.length === 0 && !busy && !loading && (
        <MotionBox
          {...containerMotion}
          sx={{
            flex: 1,
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            justifyContent: "center",
            gap: 1.75,
            textAlign: "center",
            px: 3,
          }}
        >
          <MotionBox {...itemMotion}>
            <Typography
              component="h1"
              sx={{
                fontFamily: "'Newsreader', Georgia, 'Times New Roman', serif",
                fontOpticalSizing: "auto",
                fontWeight: 500,
                fontSize: "clamp(2.2rem, 1.3rem + 2.6vw, 3.3rem)",
                lineHeight: 1.05,
                letterSpacing: "-0.01em",
                color: "text.primary",
                m: 0,
              }}
            >
              {greetingPhrase || "Dobrý den"}
              {userName && (
                <>
                  ,{" "}
                  <Box
                    component="span"
                    sx={(t) => ({
                      fontStyle: "italic",
                      backgroundImage: `linear-gradient(120deg, ${t.vars!.palette.primary.light}, ${t.vars!.palette.primary.main})`,
                      WebkitBackgroundClip: "text",
                      backgroundClip: "text",
                      WebkitTextFillColor: "transparent",
                    })}
                  >
                    {userName}
                  </Box>
                </>
              )}
            </Typography>
          </MotionBox>
          <MotionBox {...itemMotion}>
            <Typography
              component="p"
              sx={{
                fontFamily: "'Newsreader', Georgia, serif",
                fontStyle: "italic",
                fontWeight: 400,
                fontSize: "clamp(1.05rem, 0.95rem + 0.45vw, 1.3rem)",
                lineHeight: 1.55,
                color: "text.secondary",
                maxWidth: 540,
                m: 0,
              }}
            >
              Zeptejte se na cokoli, nebo přiložte fakturu — Odin ji přečte a
              připraví k uložení.
            </Typography>
          </MotionBox>
        </MotionBox>
      )}

      {/* Message bubbles */}
      {turns.map((t, i) => {
        const isUser = t.role === "user";
        return (
          <MotionBox
            key={i}
            initial={reduce ? { opacity: 0 } : { opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{
              duration: reduce ? 0.3 : 0.34,
              ease: [0.16, 1, 0.3, 1],
            }}
            sx={{
              display: "flex",
              flexDirection: "row",
              alignItems: "flex-end",
              gap: 1,
              alignSelf: isUser ? "flex-end" : "flex-start",
              maxWidth: "80%",
            }}
          >
            {!isUser && <OdinAvatar size={28} />}
            <Box
              sx={{
                px: 1.5,
                py: 1,
                borderRadius: 2,
                boxShadow: 1,
                bgcolor: isUser ? "primary.main" : "background.paper",
                // The global ::selection is primary-on-white — invisible on
                // this primary-filled bubble; invert it so selected/copied
                // text stays readable.
                ...(isUser && {
                  "& ::selection": {
                    backgroundColor: "common.white",
                    color: "primary.main",
                  },
                }),
              }}
            >
              {/* Tools the assistant consulted for this turn (Phase 2a). */}
              {!isUser && t.tools && t.tools.length > 0 && (
                <Box
                  sx={{ display: "flex", flexWrap: "wrap", gap: 0.5, mb: 0.75 }}
                >
                  {t.tools.map((tool, j) => (
                    <Chip
                      key={`${tool.name}-${j}`}
                      size="small"
                      label={`🔍 ${tool.label}`}
                      color={tool.ok ? "default" : "warning"}
                      variant="outlined"
                      sx={{ fontSize: "0.7rem", height: 22 }}
                    />
                  ))}
                </Box>
              )}
              {/* Color MUST sit on the Typography: GlobalStyles pins `p` to
                  text.secondary, which beats a color merely inherited from the
                  Box. An sx class on the element wins over that element rule. */}
              <Typography
                variant="body2"
                sx={{
                  whiteSpace: "pre-wrap",
                  color: isUser ? "common.white" : "text.primary",
                }}
              >
                {t.content}
              </Typography>
            </Box>
          </MotionBox>
        );
      })}

      {/* Busy indicator */}
      {busy && (
        <Box
          sx={{
            alignSelf: "flex-start",
            display: "flex",
            alignItems: "center",
            gap: 1,
            px: 1.5,
            py: 1,
            color: "text.secondary",
          }}
        >
          <OdinMark size={22} state="thinking" />
          <Typography variant="caption" sx={{ color: "inherit" }}>
            Pracuji…
          </Typography>
        </Box>
      )}
    </Box>
  );
}
