import "@opencode-ai/ui/styles/tailwind"
import "@opencode-ai/session-ui/styles"
import "@opencode-ai/ui/v2/styles/tailwind.css"

import { createEffect, onCleanup, onMount } from "solid-js"
import addonA11y from "@storybook/addon-a11y"
import addonDocs from "@storybook/addon-docs"
import { MetaProvider } from "@solidjs/meta"
import { addons } from "storybook/preview-api"
import { GLOBALS_UPDATED } from "storybook/internal/core-events"
import { createJSXDecorator, definePreview } from "storybook-solidjs-vite"
import { DialogProvider } from "@opencode-ai/ui/context/dialog"
import { MarkedProvider } from "@opencode-ai/ui/context/marked"
import { ThemeProvider, useTheme, type ColorScheme } from "@opencode-ai/ui/theme"
import { Font } from "@opencode-ai/ui/font"

function resolveScheme(value: unknown): ColorScheme {
  if (value === "light" || value === "dark" || value === "system") return value
  return "system"
}

const channel = addons.getChannel()

const Scheme = (props: { value?: unknown }) => {
  const theme = useTheme()
  const apply = (value?: unknown) => {
    theme.setColorScheme(resolveScheme(value))
  }
  createEffect(() => {
    apply(props.value)
  })
  createEffect(() => {
    const root = document.documentElement
    root.classList.remove("light", "dark")
    root.classList.add(theme.mode())
  })
  onMount(() => {
    const handler = (event: { globals?: Record<string, unknown> }) => {
      apply(event.globals?.theme)
    }
    channel.on(GLOBALS_UPDATED, handler)
    onCleanup(() => channel.off(GLOBALS_UPDATED, handler))
  })
  return null
}

const NewLayout = () => {
  // Mirror app.tsx BodyDesignClass so stories render with v2 (new-layout) styles
  // instead of the legacy `body:not([data-new-layout])` branch.
  onMount(() => {
    document.body.toggleAttribute("data-new-layout", true)
    document.body.classList.add("font-(family-name:--font-family-text)", "text-[13px]", "font-[440]")
    document.body.classList.remove("text-12-regular")
  })
  return null
}

const frame = createJSXDecorator((Story, context) => {
  const override = context.parameters?.themes?.themeOverride
  const selected = context.globals?.theme
  const pick = override === "light" || override === "dark" ? override : selected
  const scheme = resolveScheme(pick)
  return (
    <MetaProvider>
      <Font />
      <ThemeProvider>
        <Scheme value={scheme} />
        <NewLayout />
        <DialogProvider>
          <MarkedProvider>
            <div
              style={{
                "min-height": "100vh",
                padding: "24px",
                "background-color": "var(--background-base)",
                color: "var(--text-base)",
              }}
            >
              <Story />
            </div>
          </MarkedProvider>
        </DialogProvider>
      </ThemeProvider>
    </MetaProvider>
  )
})

export default definePreview({
  addons: [addonDocs(), addonA11y()],
  decorators: [frame],
  globalTypes: {
    theme: {
      name: "Theme",
      description: "Global theme",
      defaultValue: "light",
    },
  },
  parameters: {
    actions: {
      argTypesRegex: "^on.*",
    },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
    a11y: {
      test: "todo",
    },
  },
})
