import { Stack, TextField } from "@mui/material"
import { styled } from "@mui/styles"
import React from "react"
import { InfoButton, ToggleVisibilityButton } from "./buttons"
import { CheckedIcon, CrossIcon, LockIcon, PenIcon, PersonIcon } from "./svgIcons"

const iconsHeight = "16px"
const StyledCheckedIconSuccess = styled(CheckedIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.success.main}))
const StyledCrossIconError = styled(CrossIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.error.main}))
const StyledPenIconLight = styled(PenIcon)({height: iconsHeight, color: "#03B9E9"})
const StyledPenIconDark  = styled(PenIcon)(({theme}) => ({height: iconsHeight, color: theme.palette.primary.dark}))
const StyledPersonIconLight = styled(PersonIcon)({height: iconsHeight, color: "#03B9E9"})
const StyledLockIcon = styled(LockIcon)({height: iconsHeight, color: "#03B9E9"})

export const UsernameInput = ({infoButtonProps, ...props}) => {
    const [isSelected, setIsSelected] = React.useState(false);
    const [input, setInput] = React.useState();
    const [startAdornment, setStartAdornment] = React.useState()

    const onChange = React.useCallback((event) => {
        setInput(event.target.value)
        props.onChange?.(event)
    }, [props.onChange])

    React.useEffect(() => {
        /* Handle startAdornment */
        let Icon = StyledPersonIconLight
        let visibility = "visible"
        if (props.error) {
            Icon = StyledCrossIconError
        }
        else if (props.success) {
            Icon = StyledCheckedIconSuccess
        }
        else if (!isSelected && !input) {
            visibility = "hidden" // keep icon's space so text does not move
        }
        setStartAdornment(<Icon sx={{visibility}}/>)
    }, [props.error, props.success, isSelected, input])

    return (
        <TextField
            {...props}
            label="Choose an identifier"
            variant="standard"
            InputLabelProps={{ shrink: !!(isSelected || input) }}
            onChange={onChange}
            InputProps={{
                startAdornment,
                endAdornment: <InfoButton {...infoButtonProps}/>,
            }}
            onFocus={() => setIsSelected(true)}
            onBlur={() => setIsSelected(false)}
        />
    )
}

export const PasswordInput = ({infoButtonProps, ...props}) => {
    const [showPassword, setShowPassword] = React.useState(false);
    const [isSelected, setIsSelected] = React.useState(false);
    const [input, setInput] = React.useState();
    const [startAdornment, setStartAdornment] = React.useState()

    const toggleShowPassword = () => {
        setShowPassword((showPassword) => !showPassword);
    }

    const onChange = React.useCallback((event) => {
        setInput(event.target.value)
        props.onChange?.(event)
    }, [props.onChange])

    React.useEffect(() => {
        /* Handle startAdornment */
        let Icon = StyledLockIcon
        let visibility = "visible"
        if (props.error) {
            Icon = StyledCrossIconError
        }
        else if (props.success) {
            Icon = StyledCheckedIconSuccess
        }
        else if (!isSelected && !input) {
            visibility = "hidden" // keep icon's space so text does not move
        }
        setStartAdornment(<Icon sx={{visibility}}/>)
    }, [props.error, props.success, isSelected, input])

    return (
        <TextField
            {...props}
            label="Password"
            type={showPassword ? "text" : "password"}
            variant="standard"
            autoComplete="current-password"
            InputLabelProps={{ shrink: !!(isSelected || input) }}
            onChange={onChange}
            InputProps={{
                startAdornment,
                endAdornment: <Stack direction="row" spacing="14px">
                    <InfoButton {...infoButtonProps}/>
                    <ToggleVisibilityButton
                        visible={showPassword}
                        onClick={toggleShowPassword}
                    />
                </Stack>,
            }}
            onFocus={() => setIsSelected(true)}
            onBlur={() => setIsSelected(false)}
        />
    )
}

export const NickNameInput = (props) => {
    const [isSelected, setIsSelected] = React.useState(false);
    const [input, setInput] = React.useState();
    const [startAdornmentVisibility, setStartAdornmentVisibility] = React.useState()

    const onChange = React.useCallback((event) => {
        setInput(event.target.value)
        props.onChange?.(event)
    }, [props.onChange])

    React.useEffect(() => {
        setStartAdornmentVisibility((isSelected || input) ? "visible" : "hidden")
    }, [isSelected, input])

    return (
        <TextField
            {...props}
            label="Nickname, surname..."
            variant="standard"
            InputLabelProps={{ shrink: !!(isSelected || input) }}
            onChange={onChange}
            InputProps={{
                startAdornment: <StyledPenIconLight sx={{visibility: startAdornmentVisibility}}/>,
            }}
            onFocus={() => setIsSelected(true)}
            onBlur={() => setIsSelected(false)}
        />
    )
}

export const RegularInput = (props) => {
    const [isSelected, setIsSelected] = React.useState(false);
    const [input, setInput] = React.useState();
    const [startAdornmentVisibility, setStartAdornmentVisibility] = React.useState()
    const [endAdornmentVisibility, setEndAdornmentVisibility] = React.useState()

    const onChange = React.useCallback((event) => {
        setInput(event.target.value)
        props.onChange?.(event)
    }, [props.onChange])

    React.useEffect(() => {
        setStartAdornmentVisibility((isSelected || input) ? "visible" : "hidden")
        setEndAdornmentVisibility((isSelected || input) ? "hidden" : "visible")
    }, [isSelected, input])

    return (
        <TextField
            {...props}
            variant="standard"
            InputLabelProps={{ shrink: !!(isSelected || input) }}
            onChange={onChange}
            InputProps={{
                startAdornment: <StyledPenIconLight sx={{visibility: startAdornmentVisibility}}/>,
                endAdornment: <StyledPenIconDark sx={{visibility: endAdornmentVisibility}}/>,
            }}
            onFocus={() => setIsSelected(true)}
            onBlur={() => setIsSelected(false)}
        />
    )
}
