"use client";

import { useEffect, useRef, useState } from "react";
import { IMaskInput } from "react-imask";
import {
    InputBase,
    type InputBaseProps,
    type PolymorphicComponentProps,
} from "@mantine/core";
import CountrySelect from "@/components/PhoneInput/components/CountrySelect";
import { Country } from "@/components/PhoneInput/types";
import getInitialDataFromValue from "@/components/PhoneInput/utils/getInitialDataFromValue";
import getPhoneMask from "@/components/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"
>;

export type Props = AdditionalProps & InputProps;

const PhoneInput = ({
    initialCountryCode = "RU",
    value: _value,
    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 lastNotifiedValue = useRef<string | null>(value ?? "");

    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]);

    useEffect(() => {
        const localValue = value.trim();
        if (localValue !== lastNotifiedValue.current) {
            lastNotifiedValue.current = localValue;
            onChange(localValue);
        }
    }, [country.code, value]);

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

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

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

export default PhoneInput;
