'use client'

import Image from 'next/image'
import { useCallback, useEffect, useId, useState } from 'react'
import type { TFunction } from 'i18next'
import { FiPlus, FiX } from 'react-icons/fi'
import { GROUP_CREATE_COIN_COST, GROUP_NAME_MAX_LENGTH } from '@/lib/groups/groupSettings'

const COIN_IMAGE = '/images/room/coin.png'

function formatNCoinAmount(value: number): string {
    return value.toLocaleString()
}

export default function GroupCreateFamilyModal({
    isOpen,
    closing,
    entering,
    onClose,
    t,
    onCreated,
}: {
    isOpen: boolean
    closing: boolean
    entering: boolean
    onClose: () => void
    t: TFunction
    onCreated: (displayId: string) => void | Promise<void>
}) {
    const nameId = useId()

    const [draftName, setDraftName] = useState('')
    const [saving, setSaving] = useState(false)
    const [formError, setFormError] = useState('')
    const [coinBalance, setCoinBalance] = useState<number | null>(null)
    const [coinBalanceLoading, setCoinBalanceLoading] = useState(false)

    const resetDraft = useCallback(() => {
        setDraftName('')
        setFormError('')
        setCoinBalance(null)
    }, [])

    useEffect(() => {
        if (isOpen) {
            resetDraft()
        }
    }, [isOpen, resetDraft])

    useEffect(() => {
        if (!isOpen) return

        let cancelled = false
        setCoinBalanceLoading(true)
        void (async () => {
            try {
                const res = await fetch('/api/profile/user-info', { credentials: 'include' })
                const json = (await res.json()) as { ok?: boolean; coinBalance?: number }
                if (!cancelled && res.ok && json.ok && typeof json.coinBalance === 'number') {
                    setCoinBalance(json.coinBalance)
                }
            } catch {
                if (!cancelled) setCoinBalance(null)
            } finally {
                if (!cancelled) setCoinBalanceLoading(false)
            }
        })()

        return () => {
            cancelled = true
        }
    }, [isOpen])

    const mapApiError = (code: string, message: string) => {
        switch (code) {
            case 'INVALID_NAME':
                return message.includes('long')
                    ? t('familys.settings.errors.nameTooLong')
                    : t('familys.settings.errors.nameRequired')
            case 'INSUFFICIENT_COIN_BALANCE':
                return t('familys.createFamilyModal.errors.insufficientCoinBalance')
            default:
                return message || t('familys.createFamilyModal.errors.failed')
        }
    }

    const balanceDisplay =
        coinBalanceLoading
            ? t('common.loading')
            : typeof coinBalance === 'number'
              ? formatNCoinAmount(coinBalance)
              : '—'

    const handleSubmit = async () => {
        const name = draftName.trim()
        if (!name) {
            setFormError(t('familys.settings.errors.nameRequired'))
            return
        }
        if (name.length > GROUP_NAME_MAX_LENGTH) {
            setFormError(t('familys.settings.errors.nameTooLong'))
            return
        }

        setSaving(true)
        setFormError('')
        try {
            const res = await fetch('/api/group', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                credentials: 'include',
                body: JSON.stringify({ name }),
            })
            const json = (await res.json()) as {
                ok?: boolean
                message?: string
                code?: string
                data?: { id?: string; coinBalance?: number }
            }
            if (!res.ok || !json.ok || !json.data?.id) {
                setFormError(mapApiError(String(json.code ?? ''), json.message || ''))
                return
            }
            if (typeof json.data.coinBalance === 'number') {
                setCoinBalance(json.data.coinBalance)
            }
            await onCreated(json.data.id)
            onClose()
        } catch {
            setFormError(t('familys.createFamilyModal.errors.failed'))
        } finally {
            setSaving(false)
        }
    }

    if (!isOpen) return null

    return (
        <div
            className={`fixed inset-0 z-[600] flex items-center justify-center p-3 transition-opacity duration-200 ease-[cubic-bezier(0.56,0.12,0.12,0.98)] ${closing || entering ? 'pointer-events-none opacity-0' : 'opacity-100'}`}
        >
            <div className="absolute inset-0 bg-black/60" onClick={onClose} aria-hidden />
            <div
                role="dialog"
                aria-modal="true"
                aria-labelledby="group-create-title"
                className={`relative flex max-h-[min(90vh,560px)] w-full max-w-lg flex-col overflow-hidden rounded-xl border border-gray-200 bg-white shadow-2xl transition-[opacity,transform] duration-200 ease-[cubic-bezier(0.56,0.12,0.12,0.98)] dark:border-gray-800 dark:bg-[#0c0d0e] ${closing || entering ? 'scale-95 opacity-0' : 'scale-100 opacity-100'}`}
            >
                <div className="flex shrink-0 items-center justify-between gap-3 border-b border-gray-100 px-5 py-4 dark:border-white/10">
                    <h3
                        id="group-create-title"
                        className="flex min-w-0 items-center gap-2 text-lg font-semibold text-gray-900 dark:text-white"
                    >
                        <FiPlus
                            className="h-5 w-5 shrink-0 text-gray-500 dark:text-gray-400"
                            aria-hidden
                        />
                        <span className="truncate">{t('familys.createFamilyModal.title')}</span>
                    </h3>
                    <button
                        type="button"
                        onClick={onClose}
                        disabled={saving}
                        className="inline-flex h-8 w-8 items-center justify-center rounded-full text-gray-500 transition-colors hover:bg-gray-100 disabled:opacity-50 dark:text-gray-300 dark:hover:bg-[#1a1c21]"
                        aria-label={t('common.close')}
                    >
                        <FiX className="h-4.5 w-4.5" aria-hidden />
                    </button>
                </div>

                <div className="min-h-0 flex-1 overflow-y-auto px-5 py-4">
                    <div className="space-y-5">
                        <div className="space-y-2 rounded-lg border border-gray-100 bg-gray-50/80 px-3 py-3 dark:border-white/10 dark:bg-white/[0.03]">
                            <p className="text-sm text-gray-700 dark:text-gray-200">
                                {t('familys.createFamilyModal.coinCostHint', {
                                    cost: formatNCoinAmount(GROUP_CREATE_COIN_COST),
                                })}
                            </p>
                            <div className="flex flex-wrap items-center gap-1.5 text-sm text-gray-700 dark:text-gray-200">
                                <span className="shrink-0">
                                    {t('familys.createFamilyModal.currentNCoinBalance')}
                                </span>
                                <Image
                                    src={COIN_IMAGE}
                                    alt=""
                                    width={18}
                                    height={18}
                                    className="shrink-0 object-contain"
                                    unoptimized
                                    aria-hidden
                                />
                                <span
                                    className={`font-semibold tabular-nums ${
                                        typeof coinBalance === 'number'
                                            ? 'text-gray-900 dark:text-white'
                                            : 'text-gray-400 dark:text-gray-500'
                                    }`}
                                >
                                    {balanceDisplay}
                                </span>
                            </div>
                        </div>

                        <div>
                            <label
                                htmlFor={nameId}
                                className="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-200"
                            >
                                {t('familys.settings.nameLabel')}
                            </label>
                            <input
                                id={nameId}
                                type="text"
                                value={draftName}
                                maxLength={GROUP_NAME_MAX_LENGTH}
                                disabled={saving}
                                onChange={(e) => setDraftName(e.target.value)}
                                placeholder={t('familys.settings.namePlaceholder')}
                                className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm text-gray-900 outline-none transition-colors focus:border-gray-400 disabled:opacity-60 dark:border-white/15 dark:bg-black/30 dark:text-white dark:focus:border-white/35"
                            />
                        </div>

                        {formError ? (
                            <p className="text-sm text-red-600 dark:text-red-400" role="alert">
                                {formError}
                            </p>
                        ) : null}
                    </div>
                </div>

                <div className="flex shrink-0 items-center justify-end gap-2 border-t border-gray-100 px-5 py-4 dark:border-white/10">
                    <button
                        type="button"
                        disabled={saving}
                        onClick={onClose}
                        className="inline-flex h-10 items-center justify-center rounded-lg border border-gray-200 px-4 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:opacity-50 dark:border-white/20 dark:text-gray-200 dark:hover:bg-white/10"
                    >
                        {t('common.cancel')}
                    </button>
                    <button
                        type="button"
                        disabled={saving}
                        onClick={() => void handleSubmit()}
                        className="inline-flex h-10 items-center justify-center rounded-lg border border-gray-900 bg-gray-900 px-4 text-sm font-medium text-white transition-colors hover:bg-gray-800 disabled:opacity-50 dark:border-white dark:bg-white dark:text-gray-900 dark:hover:bg-gray-100"
                    >
                        {saving ? t('familys.createFamilyModal.submitting') : t('familys.createFamily')}
                    </button>
                </div>
            </div>
        </div>
    )
}
