import { t } from "i18next";
import { DEFAULT_LANGUAGE } from "./constants";
import {
    ProColumnType,
    RegisterType,
    TableHeaderType,
    Translation
} from "./types/appTypes";

export default function getRandomColor() {
  const letters = "0123456789ABCDEF";
  let color = "#";
  for (let i = 0; i < 6; i += 1) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

export const RGBLinearShade = (p: number, color: string) => {
  const i = parseInt;
  const r = Math.round;
  const [a, b, c, d] = color.split(",");

  const t = p < 0 ? 0 : 255 * p;

  const P = p < 0 ? 1 + p : 1 - p;
  return `rgb${d ? "a(" : "("}${r(
    i(a[3] === "a" ? a.slice(5) : a.slice(4)) * P + t
  )},${r(i(b) * P + t)},${r(i(c) * P + t)}${d ? `,${d}` : ")"}`;
};

export const parseTranslationObj = (
  prefix: any,
  obj: object,
  form: FormData
) => {
  Object.entries(obj).forEach(([key, value]) => {
    form.append(`${prefix}[${key}]`, value as string);
  });
};

/**
 * prepare data in the right format
 * @param formGroup
 */
export const parseDataToFormData = (data: any) => {
  const formData = new FormData();
  Object.entries(data).map((field: any) => {
    const key = field[0];
    const value = field[1];
    if (key === "ar" || key === "en")
      parseTranslationObj(key, value, formData);
    // cleaning  (no need to add properties with undefined, null .. etc values)
    else if (value || value === 0) formData.append(key, value);
  });
  return formData;
};

export const objPropsCalculate = (data: any) => {
  let total = 0;
  Object.entries(data).map((field: any) => {
    const value = field[1];
    if (value) total += value;
  });
  return total;
};

export const calculateRegisterBalance = (data: Partial<RegisterType>) => {
  return (
    Number(data.opening_balance || 0) +
    Number(data.total_income || 0) -
    Number(data.total_expenses || 0)
  );
};

export function getArraysDiff(arr1: Array<string>, arr2: Array<string>) {
  if (arr1.length > arr2.length)
    return arr1.filter((el) => arr2.indexOf(el) < 0);

  return arr2.filter((el) => arr1.indexOf(el) < 0);
}

export function translatedColumnTitle(
  title: string | { key: string; varKey: string },
  t2: any
): string {
  if (title && typeof title === "string") return t2(title);
  // @ts-ignore
  if (title?.key) {
    // @ts-ignore
    return t2(title.key, { var: t2(title.varKey || "") });
  }
  return "";
}

export function getModifiedColProps(
  col: TableHeaderType | Partial<ProColumnType<any>>
): Partial<ProColumnType<any>> {
  const translatedTitle = translatedColumnTitle(col.title || "", t);
  let calcColumnWidth = col.width;
  if (!calcColumnWidth) {
    const letterCount = translatedTitle.toString().length || 0;
    const uppercaseLetterCount = (
      translatedTitle.toString().match(/[A-Z]/g) || ""
    ).length;
    calcColumnWidth =
      (letterCount - uppercaseLetterCount) * 10 +
      uppercaseLetterCount * 14 +
      25;
    if (col.sorter) calcColumnWidth += 12;
    if (calcColumnWidth < 80) calcColumnWidth = 80;
  }
  return {
    title: translatedTitle,
    width: calcColumnWidth,
  };
}

export function getModifiedColumnProps(col: ProColumnType<any>, t2: any) {
  const translatedTitle = translatedColumnTitle(col.title || "", t2);
  let calcColumnWidth = col.width;
  if (!calcColumnWidth) {
    const letterCount = translatedTitle.toString().length || 0;
    const uppercaseLetterCount = (
      translatedTitle.toString().match(/[A-Z]/g) || ""
    ).length;
    calcColumnWidth =
      (letterCount - uppercaseLetterCount) * 10 +
      uppercaseLetterCount * 14 +
      25;
    if (col.sorter) calcColumnWidth += 12;
    if (calcColumnWidth < 80) calcColumnWidth = 80;
  }
  return {
    title: translatedTitle,
    width: calcColumnWidth,
  };
}

export function prepareNextKey(dataSource: any[]): number {
  return (
    dataSource.reduce((a, b) => (a.key > b.key ? a : b), {
      key: 0,
    } as any).key + 1
  );
}

export function objectArrayToFormData(
  arr: Array<Record<string, any>>,
  parentKey?: string,
  formData?: FormData
): FormData {
  const form = formData || new FormData();

  arr.forEach((obj, index) => {
    Object.keys(obj).forEach((key) => {
      const value = obj[key];
      const fullKey = parentKey ? `${parentKey}[${index}][${key}]` : `${key}`;

      if (value instanceof File) {
        form.append(fullKey, value);
      } else if (Array.isArray(value)) {
        value.forEach((v, i) => {
          form.append(`${fullKey}[${i}]`, v);
        });
      } else if (typeof value === "object" && value !== null) {
        objectArrayToFormData([value], fullKey, form);
      } else {
        form.append(fullKey, value);
      }
    });
  });

  return form;
}

/**
 * Add prefix to the invoice number
 * note: it's static prefix for all the number.
 * @param invoiceNumber
 * @returns
 */
export const addInvoiceNumberPrefix = (invoiceNumber?: string | number) => {
  return invoiceNumber ? "EP" + invoiceNumber : "";
};

/**
 * Calculate the ceil
 * @param value
 * @returns
 */
export const ceil = (value: string | number = 0) => {
  return Math.ceil(Number(value) / 100) * 100;
};

/**
 * Calculate the ceil
 * @param value
 * @returns
 */
export const formatNumbers = (value: string | number = 0) => {
  return new Intl.NumberFormat("en-US", {
    minimumFractionDigits: 0,
    maximumFractionDigits: 2,
  }).format(Number(value));
};

/**
 * Translated the current entity name
 * @param data
 * @param propName
 * @returns
 */
export const parseTranslations = (data: any) => {
  return {
    arabic_name: data?.translations?.find(
      (t: Translation) => t.locale === "ar"
    )?.name,
    name: data?.translations?.find((t: Translation) => t.locale === "en")
      ?.name,
    en: {
      name: data?.translations?.find((t: Translation) => t.locale === "en")
        ?.name,
    },
    ar: {
      name: data?.translations?.find((t: Translation) => t.locale === "ar")
        ?.name,
    },
  };
};

/**
 * Translated a foreign info (like categories in the warehouse'product)
 * @param data
 * @param propName
 * @returns
 */
export const parseTranslationLabel = (
  data: any,
  propName: string,
  translationPropName?: string
) => {
  return {
    ["arabic_" + propName]: data?.translations?.find(
      (t: Translation) => t.locale === "ar"
    )?.[translationPropName || "name"],
    [propName]: data?.translations?.find(
      (t: Translation) => t.locale === "en"
    )?.[translationPropName || "name"],
  };
};

export const getTranslatedColumnDataIndex = (dataIndex: string) => {
  return localStorage.getItem(DEFAULT_LANGUAGE) === "ar"
    ? "arabic_" + dataIndex
    : dataIndex;
};

export const saveTranslationsParse = (
  selectedRecord: any,
  dataIndex: string,
  lang: "ar" | "en",
  value: string
) => {
  return lang === "ar"
    ? {
        ar: { ...selectedRecord.ar, [dataIndex]: value },
      }
    : {
        en: { ...selectedRecord.en, [dataIndex]: value },
      };
};

export const fixNumbers = (number: string) => {
  return number.slice(0, -3);
};
