import { Colors } from '@/constants/theme';
import { isPromise } from '@/utils/tsutils';
import { ActivityIndicator, Icon } from '@ant-design/react-native';
import { type IconNames } from '@ant-design/react-native/lib/icon';
import { clsx } from 'clsx';
import { Href, Link } from "expo-router";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Pressable, Text, View, ViewStyle } from "react-native";

interface UIButtonProps {
    children?: string | React.ReactNode;
    title?: string | React.ReactNode;
    onPress?: () => PromiseLike<unknown> | unknown;
    disabled?: boolean;
    className?: string;
    textClassName?: string;
    href?: Href
    type?: 'primary' | 'second' | 'link'
    icon?: IconNames | React.ReactNode;
    style?: ViewStyle;
    loading?: boolean;
}

function ButtonTextChild({ type, disabled, textClassName, children, loading }: UIButtonProps) {

    return loading ? <View className='flex-row justify-center items-center'>
        <ActivityIndicator color={disabled ? '#888' : Colors['on-primary']['DEFAULT']} />
        <Text className={clsx(
            textClassName,
            'text-sm font-semibold', {
            'text-on-primary': !disabled && type === 'primary',
            'text-primary': !disabled && type !== 'primary',
            'text-secondary': !disabled && type === 'second',
            'text-on-surface': !disabled && !type,
            'text-on-surface-variant/65 font-normal': disabled,
        })}>{children}</Text>
    </View> : <Text className={clsx(
        textClassName,
        'text-sm font-semibold', {
        'text-on-primary': !disabled && type === 'primary',
        'text-primary': !disabled && type !== 'primary',
        'text-secondary': !disabled && type === 'second',
        'text-on-surface': !disabled && !type,
        'text-on-surface-variant/65 font-normal': disabled,
    })}>{children}</Text>
}

export default function UIButton({ onPress, href, type, icon, className, style, disabled, children, title, textClassName, loading }: UIButtonProps) {
    const [ding, setDing] = useState(loading);
    const isDisabled = Boolean(disabled || ding);

    useEffect(() => {
        setDing(loading);
    }, [loading])
    children = children || title;
    const handlePress = useCallback(() => {
        if (isDisabled) {
            return;
        }

        const res = onPress?.() as Promise<any> || undefined;
        if (isPromise(res)) {
            setDing(true);
            res.finally(() => {
                setDing(false);
            })
        }
    }, [isDisabled, onPress]);
    const inner = useMemo(() => <Pressable
        className={clsx('flex-row justify-center items-center rounded-xl py-1.5 border-2 opacity-100 active:opacity-75 active:scale-95',
            className, {
            'bg-primary border-primary': type === 'primary',
            'bg-surface border-primary/25': !type,
            'bg-surface border-on-surface/25': type === 'second',
            'bg-transparent border-transparent': type === 'link',
            'bg-primary-fixed-dim border-primary-fixed-dim': isDisabled && type === 'primary',
            'bg-gray-300 border-gray-300': isDisabled && !type,
            'bg-bg-gray-400 border-gray-200': isDisabled && type === 'second'
        })}
        disabled={isDisabled}
        onPress={handlePress}
        style={style}>
        {typeof icon === 'string' ? <Icon name={icon as IconNames} size={20} style={{ marginRight: 4, color: isDisabled ? Colors['on-surface']['variant'] : type === 'primary' ? '#fff' : type === 'second' ? Colors.secondary.DEFAULT : Colors.primary.DEFAULT }} /> : icon}
        {typeof children == 'string' ? <ButtonTextChild type={type} disabled={isDisabled} loading={ding} textClassName={textClassName}>{children}</ButtonTextChild> : children}
    </Pressable >, [children, className, ding, handlePress, icon, isDisabled, style, textClassName, type])
    if (typeof href !== 'undefined') {
        return <Link href={href} asChild>
            {inner}
        </Link>
    }

    return inner;
}
