import { useRef, useState } from 'react'
import { useMutation } from '@tanstack/react-query'
import { toast } from 'sonner'
import { Eye, EyeOff, ImagePlus, X } from 'lucide-react'
import type { AdminSettingRecord } from '@/lib/api/types'
import { apiOrigin } from '@/lib/api/client'
import { uploadImage } from '@/lib/api/upload'
import { handleServerError } from '@/lib/handle-server-error'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Switch } from '@/components/ui/switch'
import { Textarea } from '@/components/ui/textarea'
import { RichTextEditor } from '@/components/rich-text-editor'
import { isSensitiveKey } from '../groups-config'

export function SettingField({
  setting,
  value,
  onChange,
}: {
  setting: AdminSettingRecord
  value: string
  onChange: (value: string) => void
}) {
  const label = setting.label || setting.key
  const sensitive = isSensitiveKey(setting.key)

  switch (setting.type) {
    case 'boolean':
      return (
        <BooleanField
          label={label}
          settingKey={setting.key}
          value={value}
          onChange={onChange}
        />
      )
    case 'richtext':
      return (
        <div className='space-y-2'>
          <Label className='text-sm font-medium'>{label}</Label>
          <RichTextEditor
            value={value}
            onChange={onChange}
            placeholder={`${label} girin...`}
          />
        </div>
      )
    case 'textarea':
      return (
        <div className='space-y-2'>
          <Label className='text-sm font-medium'>{label}</Label>
          <Textarea
            value={value}
            onChange={(e) => onChange(e.target.value)}
            rows={4}
            placeholder={`${label} girin...`}
          />
          <SettingKeyHint settingKey={setting.key} />
        </div>
      )
    case 'json':
      return (
        <div className='space-y-2'>
          <Label className='text-sm font-medium'>{label}</Label>
          <Textarea
            value={value}
            onChange={(e) => onChange(e.target.value)}
            rows={6}
            placeholder='JSON formatında...'
            className='font-mono text-sm'
          />
        </div>
      )
    case 'image':
      return <ImageField label={label} value={value} onChange={onChange} />
    case 'color':
      return <ColorField label={label} value={value} onChange={onChange} settingKey={setting.key} />
    case 'url':
      return (
        <div className='space-y-2'>
          <Label className='text-sm font-medium'>{label}</Label>
          <Input
            type='url'
            value={value}
            onChange={(e) => onChange(e.target.value)}
            placeholder='https://...'
          />
          <SettingKeyHint settingKey={setting.key} />
        </div>
      )
    case 'text':
    default:
      return sensitive ? (
        <PasswordField label={label} value={value} onChange={onChange} settingKey={setting.key} />
      ) : (
        <div className='space-y-2'>
          <Label className='text-sm font-medium'>{label}</Label>
          <Input
            value={value}
            onChange={(e) => onChange(e.target.value)}
            placeholder={`${label} girin...`}
          />
          <SettingKeyHint settingKey={setting.key} />
        </div>
      )
  }
}

function SettingKeyHint({ settingKey }: { settingKey: string }) {
  return (
    <p className='text-[11px] text-muted-foreground/60 font-mono'>
      {settingKey}
    </p>
  )
}

function BooleanField({
  label,
  settingKey,
  value,
  onChange,
}: {
  label: string
  settingKey: string
  value: string
  onChange: (v: string) => void
}) {
  const checked = value === '1' || value === 'true'
  return (
    <div className='flex items-center justify-between rounded-xl border border-border/70 bg-muted/5 px-4 py-3'>
      <div>
        <Label className='text-sm font-medium'>{label}</Label>
        <p className='text-[11px] text-muted-foreground/60 font-mono'>
          {settingKey}
        </p>
      </div>
      <Switch
        checked={checked}
        onCheckedChange={(c) => onChange(c ? 'true' : 'false')}
      />
    </div>
  )
}

function PasswordField({
  label,
  value,
  onChange,
  settingKey,
}: {
  label: string
  value: string
  onChange: (v: string) => void
  settingKey: string
}) {
  const [show, setShow] = useState(false)
  return (
    <div className='space-y-2'>
      <Label className='text-sm font-medium'>{label}</Label>
      <div className='relative'>
        <Input
          type={show ? 'text' : 'password'}
          value={value}
          onChange={(e) => onChange(e.target.value)}
          placeholder='••••••••'
          className='pr-10'
        />
        <Button
          type='button'
          variant='ghost'
          size='icon'
          className='absolute top-1/2 right-1 size-7 -translate-y-1/2'
          onClick={() => setShow(!show)}
        >
          {show ? <EyeOff className='size-3.5' /> : <Eye className='size-3.5' />}
        </Button>
      </div>
      <SettingKeyHint settingKey={settingKey} />
    </div>
  )
}

function ColorField({
  label,
  value,
  onChange,
  settingKey,
}: {
  label: string
  value: string
  onChange: (v: string) => void
  settingKey: string
}) {
  return (
    <div className='space-y-2'>
      <Label className='text-sm font-medium'>{label}</Label>
      <div className='flex items-center gap-3'>
        <input
          type='color'
          value={value || '#000000'}
          onChange={(e) => onChange(e.target.value)}
          className='h-9 w-12 cursor-pointer rounded-lg border border-border/70'
        />
        <Input
          value={value}
          onChange={(e) => onChange(e.target.value)}
          placeholder='#000000'
          className='flex-1 font-mono text-sm'
        />
      </div>
      <SettingKeyHint settingKey={settingKey} />
    </div>
  )
}

function ImageField({
  label,
  value,
  onChange,
}: {
  label: string
  value: string
  onChange: (v: string) => void
}) {
  const inputRef = useRef<HTMLInputElement | null>(null)
  const [uploading, setUploading] = useState(false)

  const previewUrl = value
    ? value.startsWith('http')
      ? value
      : `${apiOrigin}/${value.replace(/^\/+/, '').replace(/^storage\//, '')}`
    : null

  const uploadMutation = useMutation({
    mutationFn: uploadImage,
    onSuccess: (result) => {
      onChange(result.path)
      toast.success('Görsel yüklendi')
    },
    onError: handleServerError,
  })

  async function handleFile(file: File) {
    setUploading(true)
    try {
      await uploadMutation.mutateAsync(file)
    } finally {
      setUploading(false)
    }
  }

  return (
    <div className='space-y-2'>
      <Label className='text-sm font-medium'>{label}</Label>
      <input
        ref={inputRef}
        type='file'
        accept='image/*'
        className='hidden'
        onChange={(e) => {
          const file = e.target.files?.[0]
          if (file) handleFile(file)
          e.currentTarget.value = ''
        }}
      />
      <div className='flex items-center gap-3'>
        <button
          type='button'
          onClick={() => inputRef.current?.click()}
          disabled={uploading}
          className={cn(
            'group relative flex h-16 w-24 shrink-0 items-center justify-center overflow-hidden rounded-xl border border-dashed border-border/70 bg-muted/20 transition hover:border-primary/40',
            uploading && 'pointer-events-none opacity-60'
          )}
        >
          {previewUrl ? (
            <img src={previewUrl} alt={label} className='h-full w-full object-contain' />
          ) : (
            <ImagePlus className='size-5 text-muted-foreground' />
          )}
          {uploading && (
            <div className='absolute inset-0 flex items-center justify-center bg-background/70'>
              <div className='size-4 animate-spin rounded-full border-2 border-primary border-t-transparent' />
            </div>
          )}
        </button>
        <div className='min-w-0 flex-1'>
          {value ? (
            <div className='flex items-center gap-2'>
              <p className='truncate text-xs text-muted-foreground'>{value}</p>
              <Button
                type='button'
                variant='ghost'
                size='icon'
                className='size-6 shrink-0'
                onClick={() => onChange('')}
              >
                <X className='size-3' />
              </Button>
            </div>
          ) : (
            <p className='text-xs text-muted-foreground'>Görsel yükle</p>
          )}
        </div>
      </div>
    </div>
  )
}
