import { clsx } from "clsx";
import { useState } from "react";

import { BUTTON_CAPABILITIES } from "@/constants/controls";
import { Badge } from "@/components/common/Badge";
import { Button } from "@/components/common/Button";
import { Panel } from "@/components/common/Panel";
import { ControllerDiagram, type ControllerView } from "@/components/controller/ControllerDiagram";
import { PageShell } from "@/components/layout/PageShell";
import { EventLog } from "@/components/visualizations/EventLog";
import { mockControllerBackend } from "@/services/mockControllerBackend";
import { useControllerStore } from "@/stores/controllerStore";
import { useProfileStore } from "@/stores/profileStore";

export function InputTester() {
  const [view, setView] = useState<ControllerView>("front");

  const activeController = useControllerStore((s) => s.activeController());
  const liveState = useControllerStore((s) => s.liveState);
  const eventLog = useControllerStore((s) => s.eventLog);
  const pollRateHz = useControllerStore((s) => s.pollRateHz);
  const latencyEstimateMs = useControllerStore((s) => s.latencyEstimateMs);
  const clearEventLog = useControllerStore((s) => s.clearEventLog);
  const activeProfile = useProfileStore((s) => s.activeProfile);

  const buttons = liveState?.buttons ?? {};
  const axes = liveState?.axes ?? {};
  const hasGyro = activeController?.capabilities.hasGyro ?? false;

  return (
    <PageShell title="Input Tester" description="Live view of every raw and processed input event.">
      <div className="grid grid-cols-3 gap-5">
        <Panel title="Session info">
          <dl className="grid grid-cols-2 gap-y-2 text-sm">
            <dt className="text-fg-muted">Active profile</dt>
            <dd className="text-right font-medium text-fg">{activeProfile?.name ?? "—"}</dd>
            <dt className="text-fg-muted">Poll rate</dt>
            <dd className="text-right font-mono text-fg">{pollRateHz ? `${pollRateHz} Hz` : "—"}</dd>
            <dt className="text-fg-muted">Latency estimate</dt>
            <dd className="text-right font-mono text-fg">{latencyEstimateMs ? `${latencyEstimateMs} ms` : "—"}</dd>
            <dt className="text-fg-muted">Controller</dt>
            <dd className="text-right text-fg">{activeController ? "Connected" : "None"}</dd>
          </dl>
        </Panel>

        <Panel title="Analog sticks">
          <dl className="grid grid-cols-2 gap-y-1.5 font-mono text-xs">
            <dt className="text-fg-muted">left_stick_x</dt>
            <dd className="text-right text-fg">{(axes.left_stick_x ?? 0).toFixed(3)}</dd>
            <dt className="text-fg-muted">left_stick_y</dt>
            <dd className="text-right text-fg">{(axes.left_stick_y ?? 0).toFixed(3)}</dd>
            <dt className="text-fg-muted">right_stick_x</dt>
            <dd className="text-right text-fg">{(axes.right_stick_x ?? 0).toFixed(3)}</dd>
            <dt className="text-fg-muted">right_stick_y</dt>
            <dd className="text-right text-fg">{(axes.right_stick_y ?? 0).toFixed(3)}</dd>
          </dl>
        </Panel>

        <Panel title="Triggers & gyroscope">
          <dl className="grid grid-cols-2 gap-y-1.5 font-mono text-xs">
            <dt className="text-fg-muted">left_trigger</dt>
            <dd className="text-right text-fg">{(axes.left_trigger ?? 0).toFixed(3)}</dd>
            <dt className="text-fg-muted">right_trigger</dt>
            <dd className="text-right text-fg">{(axes.right_trigger ?? 0).toFixed(3)}</dd>
            {hasGyro ? (
              <>
                <dt className="text-fg-muted">gyro_x</dt>
                <dd className="text-right text-fg">{(axes.gyro_x ?? 0).toFixed(3)}</dd>
                <dt className="text-fg-muted">gyro_y</dt>
                <dd className="text-right text-fg">{(axes.gyro_y ?? 0).toFixed(3)}</dd>
                <dt className="text-fg-muted">gyro_z</dt>
                <dd className="text-right text-fg">{(axes.gyro_z ?? 0).toFixed(3)}</dd>
              </>
            ) : (
              <dd className="col-span-2 text-fg-subtle">No gyroscope detected</dd>
            )}
          </dl>
        </Panel>

        <Panel
          title="Controller diagram"
          description={activeController?.isSimulated ? "Click a control to simulate a press." : undefined}
          className="col-span-2"
          actions={
            <div className="flex gap-1.5">
              <Button size="sm" variant={view === "front" ? "primary" : "secondary"} onClick={() => setView("front")}>
                Front
              </Button>
              <Button size="sm" variant={view === "rear" ? "primary" : "secondary"} onClick={() => setView("rear")}>
                Rear
              </Button>
            </div>
          }
        >
          <div className="mx-auto aspect-[480/280] max-w-lg">
            <ControllerDiagram
              view={view}
              buttons={buttons}
              axes={axes}
              onSelect={(id) => mockControllerBackend.pulseButton(id)}
            />
          </div>
        </Panel>

        <Panel title="Buttons">
          <div className="grid grid-cols-3 gap-2">
            {BUTTON_CAPABILITIES.map((button) => {
              const pressed = Boolean(buttons[button.id]);
              return (
                <button
                  key={button.id}
                  onClick={() => mockControllerBackend.pulseButton(button.id)}
                  className={clsx(
                    "cursor-pointer rounded-lg border px-2 py-1.5 text-center text-xs font-medium transition-colors duration-100",
                    pressed ? "border-accent bg-accent text-accent-fg" : "border-border bg-surface-2 text-fg-muted hover:border-border-strong",
                  )}
                >
                  {button.label}
                </button>
              );
            })}
          </div>
        </Panel>

        <Panel
          title="Event log"
          className="col-span-3"
          actions={
            <Badge tone="neutral">
              <Button size="sm" variant="ghost" onClick={clearEventLog}>
                Clear
              </Button>
            </Badge>
          }
        >
          <EventLog events={eventLog} />
        </Panel>
      </div>
    </PageShell>
  );
}
