/// <reference path="./locals.d.ts" />

import type { StarlightPlugin, StarlightUserConfig } from '@astrojs/starlight/types'
import { z } from 'astro/zod'

import {
  StarlightSidebarTopicsConfigSchema,
  StarlightSidebarTopicsOptionsSchema,
  type StarlightSidebarTopicsUserConfig,
  type StarlightSidebarTopicsUserOptions,
} from './libs/config'
import { throwPluginError } from './libs/plugin'
import { vitePluginStarlightSidebarTopics } from './libs/vite'

export type {
  StarlightSidebarTopicsConfig,
  StarlightSidebarTopicsUserConfig,
  StarlightSidebarTopicsOptions,
  StarlightSidebarTopicsUserOptions,
} from './libs/config'

export default function starlightSidebarTopicsPlugin(
  userConfig: StarlightSidebarTopicsUserConfig,
  userOptions?: StarlightSidebarTopicsUserOptions,
): StarlightPlugin {
  const parsedConfig = StarlightSidebarTopicsConfigSchema.safeParse(userConfig)

  if (!parsedConfig.success) {
    throwPluginError(
      `The provided plugin configuration is invalid.\n${parsedConfig.error.issues.map((issue) => issue.message).join('\n')}`,
    )
  }

  const parsedOptions = StarlightSidebarTopicsOptionsSchema.safeParse(userOptions)

  if (!parsedOptions.success) {
    throwPluginError(
      `Invalid starlight-sidebar-topics configuration:

${z.prettifyError(parsedOptions.error)}
`,
    )
  }

  const config = parsedConfig.data
  const options = parsedOptions.data

  return {
    name: 'starlight-sidebar-topics',
    hooks: {
      'config:setup'({ addIntegration, addRouteMiddleware, command, config: starlightConfig, updateConfig }) {
        if (command !== 'dev' && command !== 'build') return

        if (starlightConfig.sidebar) {
          throwPluginError(
            'It looks like you have a `sidebar` configured in your Starlight configuration. To use `starlight-sidebar-topics`, create a new topic with your sidebar items.',
            'Learn more about topic configuration at https://starlight-sidebar-topics.netlify.app/docs/configuration/',
          )
        }

        addRouteMiddleware({ entrypoint: 'starlight-sidebar-topics/middleware', order: 'pre' })

        const sidebar: StarlightUserConfig['sidebar'] = []

        for (const [index, topic] of config.entries()) {
          if ('items' in topic) {
            sidebar.push({ label: String(index), items: topic.items })
          }
        }
        updateConfig({
          components: {
            Sidebar: `starlight-sidebar-topics/overrides/Sidebar.astro`,
            ...starlightConfig.components,
          },
          sidebar,
        })

        addIntegration({
          name: 'starlight-sidebar-topics-integration',
          hooks: {
            'astro:config:setup': ({ updateConfig }) => {
              updateConfig({ vite: { plugins: [vitePluginStarlightSidebarTopics(config, options)] } })
            },
          },
        })
      },
    },
  }
}
