'use client'

import * as Tabs from '@radix-ui/react-tabs'
import {
  Bot,
  Loader2,
  AlertTriangle,
  Download,
  Layers,
  Mail,
  Users as UsersIcon,
  KeyRound,
} from 'lucide-react'
import { useState, useEffect, useCallback, useMemo } from 'react'
import { toast } from 'sonner'
import { useApiData } from '../lib/useApiData.js'
import { cmsApi } from '../lib/api.js'
import { RelationshipField } from '../fields/RelationshipField.js'
import { GeneralSettingsTab } from './settings/GeneralSettingsTab.js'
import { SeoSettingsTab } from './settings/SeoSettingsTab.js'
import { AISettingsTab } from './settings/AISettingsTab.js'
import { EmailSettingsTab } from './settings/EmailSettingsTab.js'
import { AppearanceTab } from './settings/AppearanceTab.js'
import { SecurityTab } from './settings/SecurityTab.js'
import { SettingsCard } from './settings/components.js'
import { UpdatesTab } from './settings/UpdatesTab.js'
import { Users as UsersView } from './Users.js'
import { ApiKeys as ApiKeysView } from './ApiKeys.js'

export interface SettingsProps {
  onNavigate?: (path: string) => void
  config?: any
  /** Current admin session — used to gate editing on role. */
  session?: any
  /** Initial tab when arriving without a `?tab=` query param (e.g. via the
   * legacy `/users` or `/api-keys` routes). */
  initialTab?: string
}

/**
 * Tabs that persist through the shared footer's `handleSave` (which writes
 * `defaultLayout` into the settings global). Every other tab owns its own
 * saving, so the footer must NOT render there — otherwise it shows a
 * "Settings saved successfully!" toast while persisting nothing relevant.
 * This is an allowlist on purpose: new tabs default to self-managed.
 */
const GLOBAL_SAVE_TABS = new Set(['layout'])

function readSettingsTabFromUrl(): string | null {
  if (typeof window === 'undefined') return null
  return new URLSearchParams(window.location.search).get('tab')
}

export function Settings({
  config,
  onNavigate,
  session,
  initialTab = 'general',
}: SettingsProps = {}) {
  const { data, loading, error, refetch } = useApiData<any>('/globals/settings')

  const [activeTab, setActiveTab] = useState<string>(() => readSettingsTabFromUrl() ?? initialTab)
  const [saving, setSaving] = useState(false)

  // Layout defaults
  const [defaultLayout, setDefaultLayout] = useState<Record<string, string>>({})
  const layoutConfig = config?.layout
  const layoutRegions: Array<{ name: string; collection: string; label: string }> =
    layoutConfig?.regions
      ? Object.entries(layoutConfig.regions).map(([name, region]: [string, any]) => ({
          name,
          collection: region.collection,
          label: region.label ?? name.charAt(0).toUpperCase() + name.slice(1),
        }))
      : []
  const hasLayoutRegions = layoutRegions.length > 0

  // Valid tab ids, with `layout` only available when the project configures
  // layout regions. Used to normalise deep links and keep the URL honest.
  const availableTabs = useMemo(
    () =>
      [
        'general',
        'appearance',
        ...(hasLayoutRegions ? ['layout'] : []),
        'security',
        'users',
        'api-keys',
        'seo',
        'email',
        'ai',
        'updates',
      ] as const,
    [hasLayoutRegions],
  )
  const normalizeTab = useCallback(
    (tab: string | null | undefined): string =>
      tab && (availableTabs as readonly string[]).includes(tab) ? tab : 'general',
    [availableTabs],
  )

  // Drive the active tab from the `?tab=` query param so tabs are deep-linkable
  // and survive browser back/forward (the legacy /users and /api-keys routes
  // land here via `initialTab`).
  useEffect(() => {
    function sync() {
      setActiveTab(normalizeTab(readSettingsTabFromUrl() ?? initialTab))
    }
    sync()
    window.addEventListener('popstate', sync)
    return () => window.removeEventListener('popstate', sync)
  }, [normalizeTab, initialTab])

  const changeTab = useCallback(
    (tab: string) => {
      const next = normalizeTab(tab)
      setActiveTab(next)
      onNavigate?.(`/settings?tab=${next}`)
    },
    [normalizeTab, onNavigate],
  )

  useEffect(() => {
    if (data) {
      if (data.defaultLayout && typeof data.defaultLayout === 'object') {
        setDefaultLayout(data.defaultLayout)
      }
    }
  }, [data])

  const handleSave = async () => {
    setSaving(true)
    const layoutPayload = Object.keys(defaultLayout).length > 0 ? { defaultLayout } : {}
    // Read-modify-write: the General tab owns site info / SEO defaults in the
    // same global blob, so merge against a fresh fetch instead of overwriting.
    const current = await cmsApi<Record<string, unknown>>('/globals/settings')
    const res = await cmsApi('/globals/settings', {
      method: 'PUT',
      body: JSON.stringify({
        ...(current.data ?? {}),
        ...layoutPayload,
      }),
    })
    setSaving(false)
    if (res.error) {
      toast.error(res.error)
    } else {
      toast.success('Settings saved successfully!')
    }
  }

  const tabTriggerClass =
    'text-muted-foreground hover:text-foreground data-[state=active]:border-brand data-[state=active]:text-brand px-4 py-2 text-base font-medium transition-colors data-[state=active]:border-b-2'

  if (loading) {
    return (
      <div className="flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8">
        <Loader2 className="text-primary h-6 w-6 animate-spin" />
      </div>
    )
  }

  return (
    <div className="p-3 pr-6 sm:p-4 sm:pr-8">
      {error && (
        <div
          role="alert"
          className="border-destructive/30 bg-destructive/10 text-destructive mb-4 flex items-center gap-3 rounded-lg border p-3 text-sm"
        >
          <AlertTriangle size={20} className="shrink-0" aria-hidden="true" />
          <span className="flex-1">{error}</span>
          <button
            onClick={refetch}
            className="border-destructive/40 rounded-md border px-3 py-1 transition-colors hover:opacity-80"
          >
            Retry
          </button>
        </div>
      )}

      <div className="mb-4">
        <h1 className="text-foreground mb-1 text-2xl font-medium">Settings</h1>
        <p className="text-muted-foreground text-sm">Manage your CMS configuration</p>
      </div>

      <Tabs.Root value={activeTab} onValueChange={changeTab}>
        <Tabs.List className="border-border mb-4 flex gap-1 overflow-x-auto border-b">
          <Tabs.Trigger value="general" className={tabTriggerClass}>
            General
          </Tabs.Trigger>
          <Tabs.Trigger value="appearance" className={tabTriggerClass}>
            Appearance
          </Tabs.Trigger>
          {hasLayoutRegions && (
            <Tabs.Trigger value="layout" className={tabTriggerClass}>
              <span className="flex items-center gap-1.5">
                <Layers className="h-4 w-4" />
                Layout
              </span>
            </Tabs.Trigger>
          )}
          <Tabs.Trigger value="security" className={tabTriggerClass}>
            Security
          </Tabs.Trigger>
          <Tabs.Trigger value="users" className={tabTriggerClass}>
            <span className="flex items-center gap-1.5">
              <UsersIcon className="h-4 w-4" />
              Users
            </span>
          </Tabs.Trigger>
          <Tabs.Trigger value="api-keys" className={tabTriggerClass}>
            <span className="flex items-center gap-1.5">
              <KeyRound className="h-4 w-4" />
              API Keys
            </span>
          </Tabs.Trigger>
          <Tabs.Trigger value="seo" className={tabTriggerClass}>
            SEO
          </Tabs.Trigger>
          <Tabs.Trigger value="email" className={tabTriggerClass}>
            <span className="flex items-center gap-1.5">
              <Mail className="h-4 w-4" />
              Email
            </span>
          </Tabs.Trigger>
          <Tabs.Trigger value="ai" className={tabTriggerClass}>
            <span className="flex items-center gap-1.5">
              <Bot className="h-4 w-4" />
              AI
            </span>
          </Tabs.Trigger>
          <Tabs.Trigger value="updates" className={tabTriggerClass}>
            <span className="flex items-center gap-1.5">
              <Download className="h-4 w-4" />
              Updates
            </span>
          </Tabs.Trigger>
        </Tabs.List>

        <Tabs.Content value="general">
          <GeneralSettingsTab onNavigate={onNavigate} role={session?.user?.role} />
        </Tabs.Content>

        <Tabs.Content value="appearance" className="space-y-4">
          <AppearanceTab role={session?.user?.role} config={config} />
        </Tabs.Content>

        {hasLayoutRegions && (
          <Tabs.Content value="layout" className="space-y-4">
            <SettingsCard
              title="Default Layout Variants"
              description="Select the default header, footer, and other layout variants used site-wide. Pages can override these individually or inherit from parent pages."
            >
              <div className="space-y-4">
                {layoutRegions.map((region) => (
                  <RelationshipField
                    key={region.name}
                    label={`Default ${region.label}`}
                    value={defaultLayout[region.name] ?? ''}
                    onChange={(val) => {
                      setDefaultLayout((prev) => {
                        const next = { ...prev }
                        if (val && typeof val === 'string') {
                          next[region.name] = val
                        } else {
                          delete next[region.name]
                        }
                        return next
                      })
                    }}
                    relationTo={region.collection}
                    helpText={`The ${region.label.toLowerCase()} variant used when no page in the ancestor chain specifies one`}
                  />
                ))}
              </div>
            </SettingsCard>
            <SettingsCard title="How Layout Inheritance Works">
              <ul className="text-muted-foreground space-y-1.5 text-sm">
                <li className="flex items-start gap-2">
                  <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
                    1
                  </span>
                  <span>
                    Each page can assign specific layout variants (header, footer, etc.) from the
                    document editor.
                  </span>
                </li>
                <li className="flex items-start gap-2">
                  <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
                    2
                  </span>
                  <span>
                    Child pages automatically inherit their parent&apos;s layout. For example,{' '}
                    <code className="bg-muted rounded px-1 font-mono">
                      /hampton-roads/thank-you
                    </code>{' '}
                    inherits from{' '}
                    <code className="bg-muted rounded px-1 font-mono">/hampton-roads</code>.
                  </span>
                </li>
                <li className="flex items-start gap-2">
                  <span className="bg-brand/10 text-brand mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-medium">
                    3
                  </span>
                  <span>
                    If no page in the ancestor chain sets a variant, the defaults configured above
                    are used.
                  </span>
                </li>
              </ul>
            </SettingsCard>
          </Tabs.Content>
        )}

        <Tabs.Content value="security" className="space-y-4">
          <SecurityTab role={session?.user?.role} onNavigate={onNavigate} />
        </Tabs.Content>

        <Tabs.Content value="seo" className="space-y-4">
          <SeoSettingsTab onNavigate={onNavigate} role={session?.user?.role} />
        </Tabs.Content>

        <Tabs.Content value="email" className="space-y-4">
          <EmailSettingsTab role={session?.user?.role} />
        </Tabs.Content>

        <Tabs.Content value="ai" className="space-y-4">
          <AISettingsTab role={session?.user?.role} />
        </Tabs.Content>

        <Tabs.Content value="users">
          <UsersView onNavigate={onNavigate} embedded />
        </Tabs.Content>

        <Tabs.Content value="api-keys">
          <ApiKeysView onNavigate={onNavigate} embedded />
        </Tabs.Content>

        <Tabs.Content value="updates" className="space-y-4">
          <UpdatesTab role={session?.user?.role} />
        </Tabs.Content>
      </Tabs.Root>

      {GLOBAL_SAVE_TABS.has(activeTab) && (
        <div className="mt-6 flex justify-end">
          <button
            type="button"
            onClick={handleSave}
            disabled={saving}
            className="bg-primary hover:bg-primary/90 rounded-lg px-6 py-2 text-sm text-white transition-colors disabled:opacity-50"
          >
            {saving ? 'Saving...' : 'Save Changes'}
          </button>
        </div>
      )}
    </div>
  )
}
