"use client";
import classNames from "classnames";
import style from "./TextPhone.module.css";
import { driver } from "driver.js";
import "driver.js/dist/driver.css";
import { useState, useRef } from "react";
import {
    validatePhone,
    ValidatePhoneResult,
    searchAreaCodes,
    AreaCodeSearchResult,
    sanitizeAreaCode,
    sanitizePhoneNumber,
} from "@core/helpers/validatePhone";

export type TextPhoneWidth = "80%" | "100%";

export interface TextPhoneProps {
    label: string;
    areaCode: string;
    number: string;
    width?: TextPhoneWidth;
    onChangeArea: (e: React.ChangeEvent<HTMLInputElement>) => void;
    onChangePhone: (e: React.ChangeEvent<HTMLInputElement>) => void;
}
export default function TextPhone(props: TextPhoneProps): React.ReactElement {
    const { width = "80%" } = props;
    const [showResult, setShowResult] = useState(false);
    const [validationResult, setValidationResult] = useState<ValidatePhoneResult | undefined>(undefined);

    const [searchResults, setSearchResults] = useState<AreaCodeSearchResult[]>([]);
    const [showDropdown, setShowDropdown] = useState(false);
    const [dropdownPosition, setDropdownPosition] = useState<"top" | "bottom">("bottom");

    const containerRef = useRef<HTMLDivElement>(null);
    const inputAreaCodeRef = useRef(null);
    const inputNumberRef = useRef(null);

    /* eslint-disable @typescript-eslint/no-explicit-any */
    const getWidth = (base: any) => {
        if (width === "100%") {
            return classNames(base, style.textPhoneWidth100);
        } else if (width === "80%") {
            return classNames(base, style.textPhoneWidth80);
        }
        return classNames(base, style.textPhoneWidth80);
    };

    const getInfoClass = () => {
        if (showResult) {
            if (validationResult?.isValid) {
                return classNames(style.textPhoneInfo, style.textPhoneInfoValid);
            }
            return classNames(style.textPhoneInfo, style.textPhoneInfoInvalid);
        }
    };

    const showDriveHelp = () => {
        if (!validationResult) {
            return;
        }

        if (validationResult.isValid) {
            return;
        }

        const driverObj = driver({
            allowClose: false,
            doneBtnText: "Terminar",
            nextBtnText: "Siguiente",
            prevBtnText: "Anterior",
            popoverClass: "driverjs-theme",
        });

        driverObj.setSteps([
            {
                element: inputAreaCodeRef.current!,
                popover: {
                    title: "Código de área",
                    description:
                        "En este campo debes ingresar el código de área sin el 0. Por ejemplo si tu código de área es 011, debes ingresar 11.",
                    side: "bottom",
                    popoverClass: "driverjs-theme",
                },
            },
            {
                element: inputNumberRef.current!,
                popover: {
                    title: "Número de teléfono",
                    description:
                        "En este campo debes ingresar el número de teléfono sin el 15. Por ejemplo si tu teléfono es 15-2222-3333, debes ingresar 22223333. Sin guiones y sin espacios.",
                    side: "right",
                    popoverClass: "driverjs-theme",
                },
            },
        ]);

        driverObj.drive();
    };

    const calculateDropdownPosition = () => {
        if (containerRef.current) {
            const rect = containerRef.current.getBoundingClientRect();
            const spaceBelow = window.innerHeight - rect.bottom;
            const spaceAbove = rect.top;
            const dropdownHeight = 200; // Approximate max height

            if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {
                setDropdownPosition("top");
            } else {
                setDropdownPosition("bottom");
            }
        }
    };

    return (
        <>
            <div className={getWidth(style.textPhoneLabel)}>{props.label}</div>
            <div className={getWidth(style.textPhone)} ref={containerRef}>
                <input
                    type="text"
                    ref={inputAreaCodeRef}
                    value={props.areaCode}
                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                        const val = sanitizeAreaCode(e.target.value);
                        const syntheticEvent = {
                            ...e,
                            target: {
                                ...e.target,
                                value: val,
                            },
                        } as React.ChangeEvent<HTMLInputElement>;

                        if (props.onChangeArea) {
                            props.onChangeArea(syntheticEvent);
                        }
                        setShowResult(true);
                        setValidationResult(validatePhone(val, props.number));

                        // Search for area codes
                        if (val.length > 0) {
                            const results = searchAreaCodes(val);
                            setSearchResults(results);
                            calculateDropdownPosition();
                            setShowDropdown(true);
                        } else {
                            setShowDropdown(false);
                            setSearchResults([]);
                        }
                    }}
                    onBlur={() => {
                        // Delay closing to allow click event to register
                        setTimeout(() => setShowDropdown(false), 200);
                    }}
                    placeholder="área"
                />
                <input
                    type="text"
                    ref={inputNumberRef}
                    value={props.number}
                    onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                        const val = sanitizePhoneNumber(e.target.value);
                        const syntheticEvent = {
                            ...e,
                            target: {
                                ...e.target,
                                value: val,
                            },
                        } as React.ChangeEvent<HTMLInputElement>;

                        if (props.onChangePhone) {
                            props.onChangePhone(syntheticEvent);
                        }
                        setShowResult(true);
                        setValidationResult(validatePhone(props.areaCode, val));
                    }}
                    placeholder="número (sin el 15)"
                />
                {showDropdown && (
                    <div
                        className={classNames(
                            style.dropdown,
                            dropdownPosition === "top" ? style.dropdownTop : style.dropdownBottom
                        )}
                    >
                        {searchResults.length > 0 ? (
                            searchResults.map((result) => (
                                <div
                                    key={result.code}
                                    className={style.dropdownItem}
                                    onClick={() => {
                                        const syntheticEvent = {
                                            target: { value: result.code },
                                        } as React.ChangeEvent<HTMLInputElement>;

                                        if (props.onChangeArea) {
                                            props.onChangeArea(syntheticEvent);
                                        }
                                        setValidationResult(validatePhone(result.code, props.number));
                                        setShowDropdown(false);

                                        if (inputNumberRef.current) {
                                            (inputNumberRef.current as HTMLInputElement).focus();
                                        }
                                    }}
                                >
                                    <strong>{result.code}</strong> - {result.description}
                                </div>
                            ))
                        ) : (
                            <div className={style.dropdownMessage}>
                                Código de área no encontrado. Solo ingresa el código (ej: 11) aquí y el resto
                                del número en el siguiente campo.
                            </div>
                        )}
                    </div>
                )}
            </div>
            {showResult && (
                <div className={getInfoClass()} onClick={showDriveHelp}>
                    {validationResult?.message}.{" "}
                    {!validationResult?.isValid && <b>¿Necesitas ayuda, hace clik aqui?</b>}
                </div>
            )}
        </>
    );
}
