import { useState } from 'react'
import { AxiosError } from 'axios'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { RotateCcw, Save } from 'lucide-react'
import { toast } from 'sonner'
import { api, type ApiResponse } from '@/lib/api'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { ConfigDrawer } from '@/components/config-drawer'
import { Header } from '@/components/layout/header'
import { Main } from '@/components/layout/main'
import { ProfileDropdown } from '@/components/profile-dropdown'
import { ThemeSwitch } from '@/components/theme-switch'

interface CreditRuleValues {
  register_bonus: number
  daily_check_in_reward: number
  reward_balance_cap: number
  create_mailbox_cost: number
  receive_email_cost: number
  daily_mailboxes_limit: number
  daily_emails_limit: number
}

interface CreditRule extends CreditRuleValues {
  id: number
  version: number
  updated_by: string | null
  created_at: string
  updated_at: string
}

interface CreditSettingsResponse {
  defaults: CreditRuleValues
  current: CreditRule
  timezone: string
}

const fields: Array<{
  key: keyof CreditRuleValues
  label: string
  suffix: string
}> = [
  { key: 'register_bonus', label: '注册奖励', suffix: '积分' },
  { key: 'daily_check_in_reward', label: '每日签到奖励', suffix: '积分' },
  { key: 'reward_balance_cap', label: '奖励余额上限', suffix: '积分' },
  { key: 'create_mailbox_cost', label: '创建邮箱成本', suffix: '积分/个' },
  { key: 'receive_email_cost', label: '接收邮件成本', suffix: '积分/封' },
  { key: 'daily_mailboxes_limit', label: '每日邮箱上限', suffix: '个' },
  { key: 'daily_emails_limit', label: '每日收信上限', suffix: '封' },
]

const editableValues = (rule: CreditRule): CreditRuleValues => ({
  register_bonus: rule.register_bonus,
  daily_check_in_reward: rule.daily_check_in_reward,
  reward_balance_cap: rule.reward_balance_cap,
  create_mailbox_cost: rule.create_mailbox_cost,
  receive_email_cost: rule.receive_email_cost,
  daily_mailboxes_limit: rule.daily_mailboxes_limit,
  daily_emails_limit: rule.daily_emails_limit,
})

export function CreditSettings() {
  const queryClient = useQueryClient()
  const [draft, setDraft] = useState<{
    version: number
    values: CreditRuleValues
  } | null>(null)
  const [reason, setReason] = useState('')

  const settings = useQuery({
    queryKey: ['admin', 'credit-settings'],
    queryFn: async () => {
      const response = await api.get<ApiResponse<CreditSettingsResponse>>(
        '/admin/credits/settings'
      )
      return response.data.data
    },
  })

  const values = settings.data
    ? draft?.version === settings.data.current.version
      ? draft.values
      : editableValues(settings.data.current)
    : null

  const handleError = (error: unknown) => {
    if (error instanceof AxiosError && error.response?.status === 409) {
      toast.error('规则已被其他管理员修改，请重新加载后再保存')
      void queryClient.invalidateQueries({
        queryKey: ['admin', 'credit-settings'],
      })
      return
    }
    toast.error(error instanceof Error ? error.message : '保存失败')
  }

  const save = useMutation({
    mutationFn: async () => {
      if (!settings.data || !values) return
      await api.put('/admin/credits/settings', {
        ...values,
        expected_version: settings.data.current.version,
        reason,
      })
    },
    onSuccess: async () => {
      setReason('')
      setDraft(null)
      await queryClient.invalidateQueries({
        queryKey: ['admin', 'credit-settings'],
      })
      toast.success('积分规则已更新')
    },
    onError: handleError,
  })

  const reset = useMutation({
    mutationFn: async () => {
      if (!settings.data) return
      await api.post('/admin/credits/settings/reset', {
        expected_version: settings.data.current.version,
        reason,
      })
    },
    onSuccess: async () => {
      setReason('')
      setDraft(null)
      await queryClient.invalidateQueries({
        queryKey: ['admin', 'credit-settings'],
      })
      toast.success('已恢复内置默认规则')
    },
    onError: handleError,
  })

  const updateValue = (key: keyof CreditRuleValues, next: string) => {
    const number = Number.parseInt(next, 10)
    if (!settings.data || !values) return
    setDraft({
      version: settings.data.current.version,
      values: {
        ...values,
        [key]: Number.isNaN(number) ? 0 : number,
      },
    })
  }

  const canSubmit =
    Boolean(values) &&
    reason.trim().length > 0 &&
    !save.isPending &&
    !reset.isPending

  return (
    <>
      <Header fixed>
        <div className='ms-auto flex items-center space-x-4'>
          <ThemeSwitch />
          <ConfigDrawer />
          <ProfileDropdown />
        </div>
      </Header>

      <Main className='flex flex-1 flex-col gap-6'>
        <div className='flex flex-wrap items-end justify-between gap-3'>
          <div>
            <h1 className='text-2xl font-bold'>积分规则</h1>
            <p className='text-sm text-muted-foreground'>
              当前版本 {settings.data?.current.version ?? '—'} · Asia/Shanghai
            </p>
          </div>
          <div className='text-right text-xs text-muted-foreground'>
            <p>更新人：{settings.data?.current.updated_by || '系统初始化'}</p>
            <p>
              更新时间：
              {settings.data?.current.updated_at
                ? new Date(settings.data.current.updated_at).toLocaleString()
                : '—'}
            </p>
          </div>
        </div>

        {settings.isPending && (
          <div className='py-16 text-center text-sm text-muted-foreground'>
            正在加载...
          </div>
        )}

        {settings.isError && (
          <div className='py-16 text-center text-sm text-destructive'>
            积分规则加载失败
          </div>
        )}

        {values && settings.data && (
          <>
            <div className='grid gap-x-8 gap-y-5 border-y py-6 sm:grid-cols-2 xl:grid-cols-3'>
              {fields.map((field) => (
                <div key={field.key} className='space-y-2'>
                  <div className='flex items-center justify-between gap-3'>
                    <Label htmlFor={field.key}>{field.label}</Label>
                    <span className='text-xs text-muted-foreground'>
                      默认 {settings.data.defaults[field.key]}
                    </span>
                  </div>
                  <div className='flex items-center gap-2'>
                    <Input
                      id={field.key}
                      type='number'
                      min={
                        field.key === 'register_bonus' ||
                        field.key === 'daily_check_in_reward'
                          ? 0
                          : 1
                      }
                      value={values[field.key]}
                      onChange={(event) =>
                        updateValue(field.key, event.target.value)
                      }
                    />
                    <span className='w-16 shrink-0 text-xs text-muted-foreground'>
                      {field.suffix}
                    </span>
                  </div>
                </div>
              ))}
            </div>

            <div className='flex flex-col gap-3 sm:flex-row sm:items-end'>
              <div className='flex-1 space-y-2'>
                <Label htmlFor='change-reason'>修改原因</Label>
                <Input
                  id='change-reason'
                  maxLength={200}
                  value={reason}
                  onChange={(event) => setReason(event.target.value)}
                  placeholder='必填'
                />
              </div>
              <div className='flex gap-2'>
                <Button
                  variant='outline'
                  disabled={!canSubmit}
                  onClick={() => reset.mutate()}
                >
                  <RotateCcw />
                  恢复默认
                </Button>
                <Button disabled={!canSubmit} onClick={() => save.mutate()}>
                  <Save />
                  保存规则
                </Button>
              </div>
            </div>
          </>
        )}
      </Main>
    </>
  )
}
