"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { IMaskInput } from "react-imask";
import {
    InputBase,
    type InputBaseProps,
    type PolymorphicComponentProps,
} from "@mantine/core";
import CountrySelect from "@/components/ui/PhoneInput/components/CountrySelect";
import { Country } from "@/components/ui/PhoneInput/types";
import getInitialDataFromValue from "@/components/ui/PhoneInput/utils/getInitialDataFromValue";
import getPhoneMask from "@/components/ui/PhoneInput/utils/getPhoneMask";

type AdditionalProps = {
    onChange: (value: string | null) => void;
    setPhoneMask: (mask: string) => void;
    initialCountryCode?: string;
};

type InputProps = Omit<
    PolymorphicComponentProps<typeof IMaskInput, InputBaseProps>,
    "onChange" | "defaultValue" | "value"
>;

export type Props = AdditionalProps & InputProps;

const PhoneInput = ({
    initialCountryCode = "RU",
    onChange: _onChange,
    setPhoneMask: _setPhoneMask,
    ...props
}: Props) => {
    const [mask, setMask] = useState<string>("");
    const initialData = useRef(getInitialDataFromValue(initialCountryCode));
    const [country, setCountry] = useState<Country>(
        initialData.current.country
    );
    const [value, setValue] = useState<string>("");
    const inputRef = useRef<HTMLInputElement>(null);
    const [dropdownWidth, setDropdownWidth] = useState<number>(300);

    const onChange = (numberWithoutCode: string) => {
        setValue(numberWithoutCode);
        _onChange(`+${country.callingCode} ${numberWithoutCode}`);
    };

    const setPhoneMask = (phoneMask: string, country: Country) => {
        setMask(phoneMask);
        _setPhoneMask(`+${country.callingCode} ${phoneMask}`);
    };

    useEffect(() => {
        setPhoneMask(initialData.current.format, country);
    }, [initialData.current.format]);

    const { readOnly, disabled } = props;
    const leftSectionWidth = 90;

    useEffect(() => {
        if (!inputRef.current?.offsetWidth) return;
        setDropdownWidth(inputRef.current?.offsetWidth);
    }, [inputRef.current?.offsetWidth]);

    const countrySelect = useMemo(
        () => (
            <CountrySelect
                disabled={disabled || readOnly}
                country={country}
                setCountry={country => {
                    setCountry(country);
                    setPhoneMask(getPhoneMask(country.code), country);
                    setValue("");
                    if (inputRef.current) {
                        inputRef.current.focus();
                    }
                }}
                leftSectionWidth={leftSectionWidth}
                inputWidth={dropdownWidth}
            />
        ),
        [country, leftSectionWidth, dropdownWidth, disabled, readOnly]
    );

    return (
        <InputBase
            {...props}
            component={IMaskInput}
            inputRef={inputRef}
            leftSection={countrySelect}
            leftSectionWidth={leftSectionWidth}
            styles={{
                input: {
                    fontSize: 17,
                    paddingLeft: `calc(${leftSectionWidth}px + var(--mantine-spacing-sm))`,
                },
                section: {
                    borderRight:
                        "1px solid var(--mantine-color-default-border)",
                },
            }}
            mask={mask}
            value={value}
            onAccept={onChange}
        />
    );
};

export default PhoneInput;
