import { Box, DefaultMantineColor, Flex, Input, MantineSpacing, Paper, Select, StyleProp, Switch, Text } from "@mantine/core"
import classes from './SettingsInput.module.css'
import { Children, cloneElement, HTMLInputTypeAttribute, isValidElement, MouseEvent, ReactNode, useEffect, useRef, useState } from "react";
import { useRosettaColors } from "@/app/hooks/useRosettaColors";
import { useClipboard } from "@mantine/hooks";
import { IconChevronRight } from "@tabler/icons-react";


export function SettingsInput() {}
export interface SettingsInputCopy {
    hit: string;
    placeholder?: string;
    value?: string;
    style?: any;
    mt?: StyleProp<MantineSpacing>;
}
export interface SettingsInputDefaultProps {
    hit: string;
    placeholder?: string;
    value?: string;
    disabled?: boolean;
    onChange?: (event : any) => void;
    style?: any;
    mt?: StyleProp<MantineSpacing>;
    rightSection?: ReactNode;
    type?: HTMLInputTypeAttribute;
}
export interface SettingsInputGroupProps {
    mt?: StyleProp<MantineSpacing>;
    children: any;
}
export interface SettingsInputClickableProps {
    onClick: () => void;
    hit: string;
    placeholder?: string;
    style?: any;
    mt?: StyleProp<MantineSpacing>;
    value?: string;
    rightSection?: ReactNode;
    c?: StyleProp<DefaultMantineColor>;
    rightChevronHide?: boolean;
    settingsIcon?: React.ReactNode;
}
export interface SettingsInputSelectProps {
    hit: string;
    variants: string[];
    mt?: StyleProp<MantineSpacing>;
    style?: any;
    leftSection?: ReactNode;
    onChange?: (value: string|undefined) => void;
    width?: number;
    defaultValue?: string;
}

export interface SettingsInputSwitch {
    hit: string;
    mt?: StyleProp<MantineSpacing>;
    style?: any;
    onChange?: (value: boolean) => void;
    defaultValue: boolean;
}

SettingsInput.Copy = SettingsInputCopy;
SettingsInput.Clickable = SettingsInputClickable;
SettingsInput.Default = SettingsInputDefault;
SettingsInput.Group = SettingsInputGroup;
SettingsInput.Select = SettingsInputSelect;
SettingsInput.Switch = SettingsInputSwitch;

function SettingsInputSwitch(props: SettingsInputSwitch) {
    const colors = useRosettaColors();
    const [checked, setChecked] = useState(props.defaultValue);

    useEffect(() => {
        setChecked(props.defaultValue);
    }, [props.defaultValue]);

    const onSwitch = (checked: boolean) => {
        if(props.onChange){
            props.onChange(checked);
        }
        setChecked(checked);
    }

    return (
        <Paper mt={props.mt} style={props.style} withBorder styles={{
                root: {
                    borderTop: '1px solid ' + colors.borderColor,
                    borderBottom: '1px solid ' + colors.borderColor,
                    borderLeft: '1px solid ' + colors.borderColor,
                    borderRight: '1px solid ' + colors.borderColor,
                    cursor: 'pointer'
                }
            }}
        >
            <Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
                <Text size={'sm'} fw={400}>{props.hit}</Text>
                <div style={{
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'flex-end',
                    height: 36,
                    cursor: 'pointer'
                }}>
                    <Switch
                        checked={checked}
                        onChange={(event) => onSwitch(event.currentTarget.checked)}
                        size="sm"
                    />                    
                </div>
            </Flex>
        </Paper>
    );    
}

function SettingsInputSelect(props: SettingsInputSelectProps) {
    const colors = useRosettaColors();
    const [value, setValue] = useState(props.defaultValue);

    const onChange = (selectValue : any) => {
        if(selectValue != value && selectValue != null){
            props.onChange!(selectValue);
            setValue(selectValue);
        }
    }

    return (
        <Paper mt={props.mt} style={props.style} withBorder styles={{
                root: {
                    borderTop: '1px solid ' + colors.borderColor,
                    borderBottom: '1px solid ' + colors.borderColor,
                    borderLeft: '1px solid ' + colors.borderColor,
                    borderRight: '1px solid ' + colors.borderColor,
                    cursor: 'pointer'
                }
            }}
        >
            <Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
                <Text size={'sm'} fw={400}>{props.hit}</Text>
                <div style={{
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'flex-end',
                    height: 36,
                    cursor: 'pointer'
                }}>
                    <Select allowDeselect={false} onChange={(v) => onChange(v)} style={{
                        width: props.width
                    }} leftSection={props.leftSection} color="gray" p={0} classNames={{
                    input: classes.input
                    }} variant={'unstyled'} comboboxProps={{ 
                        middlewares: { flip: true, shift: true }, offset: 0, transitionProps: { transition: 'pop', duration: 50 } }} data={props.variants} value={props.defaultValue}>
                    </Select>
                </div>
            </Flex>
        </Paper>
    );    
}

function SettingsInputCopy(props : SettingsInputCopy) {
    const colors = useRosettaColors();
    const {copied, copy} = useClipboard({
        timeout: 1500
    });
    const onClick = (e : MouseEvent) => {
        e.stopPropagation();
        copy(props.value);
    }
    return (
        <Paper mt={props.mt} style={props.style} withBorder styles={{
                root: {
                    borderTop: '1px solid ' + colors.borderColor,
                    borderBottom: '1px solid ' + colors.borderColor,
                    borderLeft: '1px solid ' + colors.borderColor,
                    borderRight: '1px solid ' + colors.borderColor,
                    cursor: 'pointer'
                }
            }}
        
            onClick={onClick}
        >
            <Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
                <Text size={'sm'} fw={400}>{props.hit}</Text>
                <div style={{
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'flex-end',
                    height: 36,
                    cursor: 'pointer'
                }} onClick={onClick}>
                {!copied && (
                    <Input defaultValue={ props.value } readOnly onClick={onClick} variant={'unstyled'} spellCheck={false} color="gray" classNames={{
                    input: classes.input
                }} placeholder={props.placeholder}></Input>)}
                               {copied && (
                    <Input defaultValue={'copied'} readOnly spellCheck={false} styles={{
                        input: {
                            color: 'var(--mantine-color-green-6)',
                            textAlign: 'right',
                            cursor: 'pointer'
                        }
                    }} variant={'unstyled'}></Input>
                )}
                </div>
            </Flex>
        </Paper>
    );
}

function SettingsInputClickable(
    props : SettingsInputClickableProps
) {
    const colors = useRosettaColors();
    const onClick = (e : MouseEvent) => {
        e.stopPropagation();
        props.onClick();
    }
    return (
        <Paper mt={props.mt} style={props.style} withBorder styles={{
            root: {
                borderTop: '1px solid ' + colors.borderColor,
                borderBottom: '1px solid ' + colors.borderColor,
                borderLeft: '1px solid ' + colors.borderColor,
                borderRight: '1px solid ' + colors.borderColor,
                cursor: 'pointer'
            }
        }}
    
        onClick={onClick}
    >
            <Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
                <Flex gap={'sm'} align={'center'}>
                    {props.settingsIcon}
                    <Text size={'sm'} c={props.c} fw={400}>{props.hit}</Text>
                </Flex>
                <div style={{
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'flex-end',
                    height: 36,
                    cursor: 'pointer'
                }} onClick={onClick}>
                    {props.rightSection && (
                        <Input defaultValue={props.value} readOnly onClick={onClick} rightSection={props.rightSection} classNames={{
                            input: classes.input
                        }} spellCheck={false} variant={'unstyled'}></Input>
                    )}
                    {!props.rightSection && (
                        <Input readOnly defaultValue={props.value} onClick={onClick} variant={'unstyled'} spellCheck={false} color="gray" classNames={{
                        input: classes.input
                    }} placeholder={props.placeholder}></Input>)
                    }
                    {!props.rightChevronHide && (<IconChevronRight size={20} onClick={onClick} color={colors.chevrons.active}></IconChevronRight>)}
                </div>
            </Flex>
        </Paper>
    );
}

function SettingsInputDefault(props : SettingsInputDefaultProps) {
    const colors = useRosettaColors();
    const input = useRef<any>(undefined);

    const onClick = (e : MouseEvent) => {
        e.stopPropagation();
        if(!props.disabled){
            input.current.focus();
            return;
        }
    }
    return (<>
        <Paper mt={props.mt} style={props.style} withBorder styles={{
                root: {
                    borderTop: '1px solid ' + colors.borderColor,
                    borderBottom: '1px solid ' + colors.borderColor,
                    borderLeft: '1px solid ' + colors.borderColor,
                    borderRight: '1px solid ' + colors.borderColor,
                    cursor: 'pointer'
                }
            }}
        
            onClick={onClick}
        >
            <Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
                <Text size={'sm'} fw={400}>{props.hit}</Text>
                <div style={{
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'flex-end',
                    height: 36,
                    cursor: 'pointer'
                }} onClick={onClick}>
                {props.rightSection && (
                    <Input type={props.type} defaultValue={props.value} readOnly onClick={onClick} rightSection={props.rightSection} classNames={{
                        input: classes.input
                    }} spellCheck={false} variant={'unstyled'}></Input>
                )}
                {!props.rightSection && (
                    <Input type={props.type} defaultValue={!props.onChange ? props.value : undefined} value={!props.onChange ? undefined : props.value} ref={input} disabled={props.disabled} onClick={(e) => {
                         onClick(e)
                    }} onChange={props.onChange} variant={'unstyled'} spellCheck={false} color="gray" classNames={{
                    input: classes.input
                }} placeholder={props.placeholder}></Input>)
                }
                </div>
            </Flex>
        </Paper>
    </>)
}


function SettingsInputGroup(props : SettingsInputGroupProps) {
    const colors = useRosettaColors();

    const childrenArray = Children.toArray(props.children).filter(
        (child): child is React.ReactElement<{ style?: React.CSSProperties }> =>
            isValidElement(child)
    );
    return (
        <Box mt={props.mt}>
            {childrenArray.map((child, index) => {
                const isFirst = index === 0;
                const isLast = index === childrenArray.length - 1;
                return cloneElement(child, {
                    style: {
                        borderRadius: isFirst
                            ? "var(--mantine-radius-default) var(--mantine-radius-default) 0 0"
                            : isLast
                            ? "0 0 var(--mantine-radius-default) var(--mantine-radius-default)"
                            : "0",
                        borderTop: isLast ? 'unset' : '1px solid ' + colors.borderColor,
                        borderBottom: isFirst ? '1px solid ' + colors.borderColor : '1px solid ' + colors.borderColor,
                        ...(child.props.style || {}),
                    },
                });
            })}
        </Box>
    );
}