import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
import { AppDispatch } from "@/store/store";
import axiosInstanceClient from "./axiosClient";
import { setIsLoading, updateUser } from "@/store/auth.slice";
import ShowAlertMixin from "@/shared/ShowAlertMixin";
import { setLocation } from "@/store/location.slice";
import { setAddresses, setAddressesLoading } from "@/store/address.slice";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}
export const validationPhoneNumber = ({
  t,
  context,
  value,
}: {
  t: any;
  context: any;
  value: any;
}): boolean => {
  let phoneLimit = context.parent.phone_limit;
  if (!phoneLimit) return true;
  if (value && value.length !== parseInt(phoneLimit)) {
    return context.createError({
      message: t("validations.phoneLimit", {
        length: `${phoneLimit}`,
      }),
      path: "phone",
    });
  }
  return true;
};

export const updateURLParams = ({
  params,
  router,
  pathname,
  page,
  refetch,
}: {
  params: { [key: string]: string | null };
  router: any;
  pathname: any;
  page?: boolean;
  refetch?: () => void;
}) => {
  const newSearchParams = new URLSearchParams(window.location.search);
  Object.entries(params).forEach(([key, value]) => {
    if (value === null) {
      newSearchParams.delete(key);
    } else {
      newSearchParams.set(key, value);
    }
    if (page) newSearchParams.delete("page");
    if (refetch) refetch();
  });
  router.replace(`${pathname}?${newSearchParams.toString()}`, {
    scroll: false,
  });
};

export const UpdateProfile = async ({
  dispatch,
}: {
  dispatch: AppDispatch;
}) => {
  try {
    const { data } = await axiosInstanceClient.get("client/profile");
    if (data.status == "success") dispatch(updateUser(data.data));
  } catch (error: any) {
    ShowAlertMixin({
      icon: "error",
      title: error?.response?.data?.message,
    });
  } finally {
    dispatch(setIsLoading(false));
  }
};

export const fetchAddressData = async ({
  dispatch,
}: {
  dispatch: AppDispatch;
}) => {
  try {
    const { data } = await axiosInstanceClient.get(
      "client/addresses?paginate=0",
    );
    dispatch(setAddresses({ data: data?.data || [] }));
    const location = data?.data?.filter((ele: any) => +ele.is_default == 1)[0];
    if (location) {
      dispatch(
        setLocation({
          id: location?.id,
          is_default: location?.is_default,
          phone_code: location?.contact?.phone_code,
          phone: location?.contact?.phone,
          country: location?.location?.country,
          city: location?.location?.city,
          district: location?.location?.district,
          lng: location?.location?.longitude,
          lat: location?.location?.latitude,
          description: location?.description,
          isLoading: false,
        }),
      );
    }
  } catch (error: any) {
    ShowAlertMixin({
      icon: "error",
      title: error?.response?.data?.message,
    });
  } finally {
    dispatch(setAddressesLoading({ isLoading: false }));
  }
};

export const cleanPath = ({
  path,
  keepSearchParams = false,
}: {
  path: string;
  keepSearchParams?: boolean;
}) => {
  const pathWithoutQuery = keepSearchParams ? path : path.split("?")[0];
  return pathWithoutQuery.endsWith("/") && pathWithoutQuery !== "/"
    ? pathWithoutQuery.slice(0, -1)
    : pathWithoutQuery;
};

export const parseHtml = ({ html }: { html: string }) => {
  const parser = new DOMParser();
  const doc = parser.parseFromString(html, "text/html");
  return doc.body.textContent;
};

export const formatLocalDate = ({ date }: { date: Date | string }) => {
  if (!date) return "";
  const dateObj = new Date(date);
  const year = dateObj.getFullYear();
  const month = String(dateObj.getMonth() + 1).padStart(2, "0");
  const day = String(dateObj.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
};

export const getBase64 = (file: File): Promise<string> =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = (error) => reject(error);
  });
