"use client"
import React from "react"
import { Client, Room } from "colyseus.js"
import { Button } from "@mui/material"

type RealityLike = {
  barracks?: Record<string, number>
  entities?: Record<string, unknown>
  hero?: unknown
}

type GameStateLike = {
  realities?: Record<string, RealityLike> | Map<string, RealityLike>
  home_reality_index?: number
  target_reality_index?: number
}

const ROOM_NAME = "main_game";

function toRealityEntries(realities: GameStateLike["realities"]): Array<[string, RealityLike]> {
  if (!realities) return []
  if (typeof (realities as Map<string, RealityLike>).entries === "function") {
    return Array.from((realities as Map<string, RealityLike>).entries())
  }
  return Object.entries(realities as Record<string, RealityLike>)
}

export default function VisionsOfReality() {
  const [client] = React.useState(() => new Client(process.env.SERVER_URL))
  const [room, setRoom] = React.useState<Room<GameStateLike> | null>(null)
  const [status, setStatus] = React.useState("disconnected")
  const [tick, setTick] = React.useState(0)
  const [homeRealityIndex, setHomeRealityIndex] = React.useState<number | null>(null)
  const [targetRealityIndex, setTargetRealityIndex] = React.useState<number | null>(null)
  const [viewRealityIndex, setViewRealityIndex] = React.useState<number | null>(null)

  React.useEffect(() => {
    return () => {
      room?.leave()
    }
  }, [room])

  const connect = async () => {
    setStatus("connecting")
    try {
      const joined = await client.joinOrCreate<GameStateLike>(ROOM_NAME)
      setRoom(joined)
      setStatus("connected")
      setHomeRealityIndex(joined.state?.home_reality_index ?? null)
      setTargetRealityIndex(joined.state?.target_reality_index ?? null)
      setViewRealityIndex(joined.state?.home_reality_index ?? null)

      joined.onStateChange((state) => {
        setHomeRealityIndex(state.home_reality_index ?? null)
        setTargetRealityIndex(state.target_reality_index ?? null)
        setViewRealityIndex((prev) => (prev === null ? state.home_reality_index ?? null : prev))
        setTick((t) => t + 1)
      })

      joined.onLeave(() => {
        setStatus("disconnected")
        setRoom(null)
      })
    } catch (err) {
      console.error("Failed to join room", err)
      setStatus("error")
    }
  }

  const disconnect = async () => {
    await room?.leave()
    setRoom(null)
    setStatus("disconnected")
  }

  const realities = toRealityEntries(room?.state?.realities)
  const currentReality =
    viewRealityIndex !== null
      ? realities.find(([id]) => Number(id) === viewRealityIndex)?.[1]
      : undefined

  const sendTarget = (index: number) => {
    if (!room) return
    setTargetRealityIndex(index)
    room.send("set_target_reality_index", { index })
  }

  return (
    <div
      style={{
        minHeight: "100vh",
        display: "grid",
        gridTemplateRows: "auto 1fr",
        gap: 12,
        padding: 12,
      }}
    >
      <div style={{ display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
        <Button variant="contained" disabled={status === "connected"} onClick={connect}>
          Join
        </Button>
        <Button variant="outlined" disabled={!room} onClick={disconnect}>
          Leave
        </Button>
        <div>status: {status}</div>
        <div>tick: {tick}</div>
        <div>home: {homeRealityIndex ?? "?"}</div>
        <div>view: {viewRealityIndex ?? "?"}</div>
        <div>target: {targetRealityIndex ?? "?"}</div>
        <div
          style={{
            display: "grid",
            gridTemplateColumns: "repeat(3, 44px)",
            gap: 6,
          }}
        >
          {Array.from({ length: 9 })
            .map((_, index) => index)
            .filter((index) => index !== 4)
            .filter((index) => index !== homeRealityIndex)
            .map((index) => {
              const isTarget = targetRealityIndex === index
              const isViewing = viewRealityIndex === index
              return (
                <button
                  key={index}
                  onClick={() => {
                    sendTarget(index)
                    setViewRealityIndex(index)
                  }}
                  style={{
                    height: 44,
                    borderRadius: "50%",
                    border: "1px solid #333",
                    background: isTarget ? "#f0b429" : isViewing ? "#9ae6b4" : "#f7f7f7",
                    cursor: "pointer",
                  }}
                  title={`Reality ${index}`}
                >
                  {index}
                </button>
              )
            })}
        </div>
      </div>

      <div
        style={{
          display: "grid",
          gap: 12,
          gridTemplateRows: "auto 1fr auto",
          minHeight: 0,
        }}
      >
        <div style={{ fontWeight: 600, fontSize: 18 }}>
          Reality {viewRealityIndex ?? "?"} {viewRealityIndex === homeRealityIndex ? "(home)" : ""}
        </div>

        <div
          style={{
            display: "grid",
            gridTemplateColumns: "repeat(15, 1fr)",
            gridAutoRows: "1fr",
            gap: 2,
            height: "100%",
            minHeight: 0,
            background: "#fafafa",
            padding: 8,
            borderRadius: 8,
            border: "1px solid #e5e7eb",
          }}
        >
          {Array.from({ length: 225 }).map((__, cellIndex) => (
            <div
              key={cellIndex}
              style={{
                aspectRatio: "1 / 1",
                background: "#e5e7eb",
              }}
            />
          ))}
        </div>

        <div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
          <div>barracks: {currentReality?.barracks ? Object.keys(currentReality.barracks).length : 0}</div>
          <div>entities: {currentReality?.entities ? Object.keys(currentReality.entities).length : 0}</div>
          <div>hero: {currentReality?.hero ? "yes" : "no"}</div>
        </div>
      </div>
    </div>
  )
}
