import { PhoneFilled } from "@ant-design/icons";
import { Button, Input, Space } from "antd";
import i18n from "i18next";
import parsePhoneNumber from "libphonenumber-js";
import { forwardRef, useMemo, useState } from "react";
import "./phone-form-item.styles.scss";

/**
 * Formats a phone number for display purposes. If the input value is a valid phone number, it will be formatted in a
 * national format (e.g., (123) 456-7890 for US/CA). If the input is not a valid phone number, it will be returned as-is.
 * @param value
 * @returns {*}
 */
const formatPhoneDisplayValue = (value) => {
  if (!value) return value;

  try {
    const parsedPhone = parsePhoneNumber(value, "CA");
    return parsedPhone?.isValid() ? parsedPhone.formatNational() : value;
  } catch {
    return value;
  }
};

/**
 * Generates a "tel:" URL for a phone number if it's valid. If the input value is a valid phone number, it will return a
 * URL in the format "tel:+1234567890". If the input is not a valid phone number, it will attempt to trim whitespace and
 * return a "tel:" URL with the raw value, or null if the trimmed value is empty.
 * @param value
 * @returns {string|null}
 */
const getPhoneActionHref = (value) => {
  if (!value) return null;

  try {
    const parsedPhone = parsePhoneNumber(value, "CA");
    if (parsedPhone?.isValid()) return `tel:${parsedPhone.number}`;
  } catch {
    // Fall back to the raw value below.
  }

  const trimmedValue = String(value).trim();
  return trimmedValue ? `tel:${trimmedValue}` : null;
};

const FormItemPhone = forwardRef(function FormItemPhone(
  { formatDisplayOnly = false, showPhoneAction = false, value, onBlur, onFocus, ...props },
  ref
) {
  const [isFocused, setIsFocused] = useState(false);
  const displayValue = useMemo(() => {
    if (!formatDisplayOnly || isFocused) return value;
    return formatPhoneDisplayValue(value);
  }, [formatDisplayOnly, isFocused, value]);
  const phoneActionHref = useMemo(() => (showPhoneAction ? getPhoneActionHref(value) : null), [showPhoneAction, value]);

  const input = (
    <Input
      ref={ref}
      {...props}
      value={displayValue}
      onFocus={(event) => {
        setIsFocused(true);
        onFocus?.(event);
      }}
      onBlur={(event) => {
        setIsFocused(false);
        onBlur?.(event);
      }}
    />
  );

  if (!showPhoneAction) return input;

  return (
    <Space.Compact style={{ width: "100%" }}>
      {input}
      {phoneActionHref ? (
        <Button icon={<PhoneFilled />} href={phoneActionHref} />
      ) : (
        <Button icon={<PhoneFilled />} disabled />
      )}
    </Space.Compact>
  );
});

export default FormItemPhone;

export const PhoneItemFormatterValidation = () => ({
  async validator(rule, value) {
    if (!value) {
      return Promise.resolve();
    } else {
      const p = parsePhoneNumber(value, "CA");
      if (p && p.isValid()) {
        return Promise.resolve();
      } else {
        return Promise.reject(i18n.t("general.validation.invalidphone"));
      }
    }
  }
});
