import { startTransition, useEffect, useMemo, useRef, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import {
  Loader2,
  RefreshCw,
  Save,
  Trash2,
} from 'lucide-react'
import {
  clearSettingsCache,
  fetchSettings,
  updateSettings,
} from '@/lib/api/settings'
import type { AdminSettingRecord } from '@/lib/api/types'
import { handleServerError } from '@/lib/handle-server-error'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Header } from '@/components/layout/header'
import { Main } from '@/components/layout/main'
import { ProfileDropdown } from '@/components/profile-dropdown'
import { ThemeSwitch } from '@/components/theme-switch'
import { groupsConfig } from './groups-config'
import { SettingsGroupPanel } from './components/settings-group-panel'

export function SettingsPage() {
  const queryClient = useQueryClient()
  const [activeGroup, setActiveGroup] = useState('general')
  const [localValues, setLocalValues] = useState<Record<string, string>>({})
  const [originalValues, setOriginalValues] = useState<Record<string, string>>({})

  const settingsQuery = useQuery({
    queryKey: ['settings'],
    queryFn: fetchSettings,
  })

  useEffect(() => {
    if (settingsQuery.data) {
      const values: Record<string, string> = {}
      for (const setting of settingsQuery.data) {
        values[setting.key] = setting.value ?? ''
      }
      startTransition(() => {
        setLocalValues(values)
        setOriginalValues(values)
      })
    }
  }, [settingsQuery.data])

  const settingsByGroup = useMemo(() => {
    const map: Record<string, AdminSettingRecord[]> = {}
    if (settingsQuery.data) {
      for (const setting of settingsQuery.data) {
        const group = setting.group || 'general'
        if (!map[group]) map[group] = []
        map[group].push(setting)
      }
    }
    return map
  }, [settingsQuery.data])

  const dirtyKeys = useMemo(() => {
    const keys: string[] = []
    for (const [key, value] of Object.entries(localValues)) {
      if (value !== (originalValues[key] ?? '')) {
        keys.push(key)
      }
    }
    return keys
  }, [localValues, originalValues])

  const isDirty = dirtyKeys.length > 0

  const dirtyByGroup = useMemo(() => {
    const map: Record<string, number> = {}
    if (!settingsQuery.data) return map
    for (const key of dirtyKeys) {
      const setting = settingsQuery.data.find((s) => s.key === key)
      if (setting) {
        const g = setting.group || 'general'
        map[g] = (map[g] ?? 0) + 1
      }
    }
    return map
  }, [dirtyKeys, settingsQuery.data])

  const updateMutation = useMutation({
    mutationFn: async () => {
      const payload: Record<string, string | null> = {}
      for (const key of dirtyKeys) {
        const setting = settingsQuery.data?.find((s) => s.key === key)
        if (setting) {
          payload[`${setting.group}.${key}`] = localValues[key] || null
        }
      }
      return updateSettings(payload)
    },
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['settings'] })
      toast.success(`${dirtyKeys.length} ayar güncellendi`)
    },
    onError: handleServerError,
  })

  const cacheMutation = useMutation({
    mutationFn: clearSettingsCache,
    onSuccess: () => toast.success('Ayar cache temizlendi'),
    onError: handleServerError,
  })

  function handleChange(key: string, value: string) {
    setLocalValues((prev) => ({ ...prev, [key]: value }))
  }

  const activeConfig = groupsConfig.find((g) => g.key === activeGroup)

  return (
    <>
      <Header
        fixed
        className='border-b border-border/60 bg-background/85 backdrop-blur'
      >
        <div>
          <p className='text-[11px] font-semibold tracking-[0.26em] text-muted-foreground uppercase'>
            Sistem
          </p>
          <p className='text-sm font-semibold tracking-tight'>Ayarlar</p>
        </div>
        <div className='ms-auto flex items-center gap-3'>
          {isDirty && (
            <Badge variant='secondary' className='rounded-full text-xs'>
              {dirtyKeys.length} değişiklik
            </Badge>
          )}
          <Button
            variant='outline'
            size='sm'
            className='rounded-xl'
            onClick={() => settingsQuery.refetch()}
            disabled={settingsQuery.isFetching}
          >
            <RefreshCw
              className={settingsQuery.isFetching ? 'animate-spin' : ''}
            />
          </Button>
          <Button
            size='sm'
            className='rounded-xl'
            disabled={!isDirty || updateMutation.isPending}
            onClick={() => updateMutation.mutate()}
          >
            {updateMutation.isPending ? (
              <Loader2 className='animate-spin' />
            ) : (
              <Save />
            )}
            Kaydet
          </Button>
          <ThemeSwitch />
          <ProfileDropdown />
        </div>
      </Header>

      <Main>
        {settingsQuery.isLoading ? (
          <div className='flex h-64 items-center justify-center text-muted-foreground'>
            <Loader2 className='mr-2 size-5 animate-spin' />
            Ayarlar yükleniyor...
          </div>
        ) : (
          <div className='flex gap-6'>
            {/* Sidebar */}
            <div className='w-56 shrink-0'>
              <div className='sticky top-20'>
                <ScrollArea className='max-h-[calc(100vh-6rem)]'>
                  <nav className='space-y-1 pr-2'>
                    {groupsConfig.map((group) => {
                      const Icon = group.icon
                      const dirty = dirtyByGroup[group.key] ?? 0
                      const hasSettings = (settingsByGroup[group.key] ?? []).length > 0

                      return (
                        <button
                          key={group.key}
                          type='button'
                          onClick={() => setActiveGroup(group.key)}
                          className={cn(
                            'flex w-full items-center gap-2.5 rounded-xl px-3 py-2 text-left text-sm transition',
                            activeGroup === group.key
                              ? 'bg-primary/10 font-medium text-primary'
                              : 'text-muted-foreground hover:bg-muted/50 hover:text-foreground',
                            !hasSettings && 'opacity-50'
                          )}
                        >
                          <Icon className='size-4 shrink-0' />
                          <span className='flex-1 truncate'>{group.label}</span>
                          {dirty > 0 && (
                            <span className='flex h-5 min-w-5 items-center justify-center rounded-full bg-amber-500/20 px-1.5 text-[10px] font-semibold text-amber-700'>
                              {dirty}
                            </span>
                          )}
                        </button>
                      )
                    })}
                  </nav>

                  <div className='mt-6 border-t border-border/50 pt-4 pr-2'>
                    <Button
                      type='button'
                      variant='ghost'
                      size='sm'
                      className='w-full justify-start gap-2 rounded-xl text-xs text-muted-foreground'
                      disabled={cacheMutation.isPending}
                      onClick={() => cacheMutation.mutate()}
                    >
                      <Trash2 className='size-3.5' />
                      Cache temizle
                    </Button>
                  </div>
                </ScrollArea>
              </div>
            </div>

            {/* Content */}
            <div className='min-w-0 flex-1'>
              {activeConfig && (
                <div className='mb-6'>
                  <div className='flex items-center gap-3'>
                    <div className='flex h-10 w-10 items-center justify-center rounded-xl bg-primary/10'>
                      <activeConfig.icon className='size-5 text-primary' />
                    </div>
                    <div>
                      <h2 className='text-lg font-semibold'>
                        {activeConfig.label}
                      </h2>
                      <p className='text-sm text-muted-foreground'>
                        {activeConfig.description}
                      </p>
                    </div>
                  </div>
                </div>
              )}

              <div className='rounded-2xl border border-border/70 bg-card p-6 shadow-sm'>
                {activeConfig && (
                  <SettingsGroupPanel
                    group={activeConfig}
                    settings={settingsByGroup[activeGroup] ?? []}
                    values={localValues}
                    onChange={handleChange}
                  />
                )}
              </div>

              {isDirty && (
                <div className='sticky bottom-4 mt-4 flex items-center justify-between rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 shadow-lg dark:border-amber-900/50 dark:bg-amber-950/50'>
                  <p className='text-sm font-medium text-amber-800 dark:text-amber-200'>
                    {dirtyKeys.length} kaydedilmemiş değişiklik
                  </p>
                  <div className='flex gap-2'>
                    <Button
                      type='button'
                      variant='outline'
                      size='sm'
                      className='rounded-xl'
                      onClick={() => {
                        setLocalValues(originalValues)
                      }}
                    >
                      Geri al
                    </Button>
                    <Button
                      size='sm'
                      className='rounded-xl'
                      disabled={updateMutation.isPending}
                      onClick={() => updateMutation.mutate()}
                    >
                      {updateMutation.isPending ? (
                        <Loader2 className='animate-spin' />
                      ) : (
                        <Save />
                      )}
                      Kaydet
                    </Button>
                  </div>
                </div>
              )}
            </div>
          </div>
        )}
      </Main>
    </>
  )
}
