"use client";

import { useEffect, useRef, useState } from "react";
import { IMaskInput } from "react-imask";
import {
    InputBase,
    type InputBaseProps,
    type PolymorphicComponentProps,
} from "@mantine/core";
import { useUncontrolled } from "@mantine/hooks";
import CountrySelect from "@/components/PhoneInput/components/CountrySelect";
import getFormat from "@/components/PhoneInput/utils/getFormat";
import getInitialDataFromValue from "@/components/PhoneInput/utils/getInitialDataFromValue";

export type Props = {
    initialCountryCode?: string;
    defaultValue?: string;
} & Omit<
    PolymorphicComponentProps<typeof IMaskInput, InputBaseProps>,
    "onChange" | "defaultValue"
> & { onChange: (value: string | null) => void };

const PhoneInput = ({
    initialCountryCode = "RU",
    value: _value,
    onChange: _onChange,
    defaultValue,
    ...props
}: Props) => {
    const [value, onChange] = useUncontrolled({
        value: _value,
        defaultValue,
        onChange: _onChange,
    });
    const initialData = useRef(
        getInitialDataFromValue(value, initialCountryCode)
    );
    const [country, setCountry] = useState(initialData.current.country);
    const [format, setFormat] = useState(initialData.current.format);
    const [localValue, setLocalValue] = useState(
        initialData.current.localValue
    );
    const inputRef = useRef<HTMLInputElement>(null);
    const [dropdownWidth, setDropdownWidth] = useState<number>(300);

    const lastNotifiedValue = useRef<string | null>(value ?? "");

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

    useEffect(() => {
        if (
            typeof value !== "undefined" &&
            value !== lastNotifiedValue.current
        ) {
            const initialData = getInitialDataFromValue(
                value,
                initialCountryCode
            );
            lastNotifiedValue.current = value;
            setCountry(initialData.country);
            setFormat(initialData.format);
            setLocalValue(initialData.localValue);
        }
    }, [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);
                        setFormat(getFormat(country.code));
                        setLocalValue("");
                        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={format.mask}
            value={localValue}
            onAccept={value => setLocalValue(value)}
        />
    );
};

export default PhoneInput;
