import { api as apiCfg } from '@/config.json';
import { Colors } from '@/constants/theme';
import api from '@/utils/api';
import { Icon, Modal } from '@ant-design/react-native';
import { Image } from 'expo-image';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Pressable, TextInput, View } from 'react-native';

function blobToDataUrl(blob: Blob) {
    return new Promise<string>((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result as string);
        reader.onerror = reject;
        reader.readAsDataURL(blob);
    });
}

export interface CaptchaRes {
    ok: boolean;
    code?: string;
    sid?: string;
}

export default function CaptchaBox({
    onClose,
    visible,
}: {
    onClose: (res: CaptchaRes) => void;
    visible: boolean;
}) {
    const [internalVisible, setInternalVisible] = useState(false);
    const [imageUri, setImageUri] = useState<string>(null!);
    const [code, setCode] = useState('');
    const sessionIdRef = useRef<string | undefined>(undefined);
    const resultRef = useRef<CaptchaRes>({ ok: false });

    const refresh = useCallback(async () => {
        try {
            const res = await api.rawRequest<Blob>({
                url: `${apiCfg.url}common/captcha?t=${Date.now()}`,
                timeout: 15000,
                responseType: 'blob',
            });
            sessionIdRef.current = res.headers['x-session_id'] as string;
            setImageUri(await blobToDataUrl(res.data));
        } catch (e) {
            console.error(e);
        }
    }, []);

    useEffect(() => {
        setInternalVisible(visible);
        setImageUri(null!);
        if (visible) {
            refresh();
            setCode('');
        }
    }, [refresh, visible]);

    return (
        <Modal
            visible={internalVisible}
            transparent
            style={{ width: 208 }}
            onClose={() => onClose(resultRef.current)}
            footer={[
                {
                    text: '取消',
                    style: { color: Colors.textSecondary },
                    onPress: () => {
                        resultRef.current.ok = false;
                        setInternalVisible(false);
                    },
                },
                {
                    text: '确认',
                    onPress: () => {
                        resultRef.current.ok = true;
                        resultRef.current.code = code;
                        resultRef.current.sid = sessionIdRef.current;
                        setInternalVisible(false);
                    },
                },
            ]}
        >
            <View className="w-48 items-center justify-center">
                <View className="w-full">
                    {imageUri ? (
                        <Image
                            style={{ width: 175, height: 44 }}
                            className="w-full h-12 bg-gray-500"
                            source={{ uri: imageUri }}
                        />
                    ) : (
                        <View className="w-full h-12 bg-gray-200" />
                    )}
                    <Pressable
                        className="w-8 h-8 p-1 justify-center items-center"
                        onPress={refresh}
                    >
                        <Icon name="reload" />
                    </Pressable>
                </View>
                <View className="h-8 flex-row items-center rounded-2xl bg-surface-container-low p-0">
                    <TextInput
                        value={code}
                        onChangeText={setCode}
                        keyboardType="phone-pad"
                        maxLength={6}
                        placeholder="请输入图中字符"
                        placeholderTextColor="#9ca3af"
                        className="flex-1 h-8 text-center p-0 text-sm font-medium text-on-surface"
                    />
                </View>
            </View>
        </Modal>
    );
}
