import { fetchApi } from "../../util/http-utils";
import { getStoreName } from "../../util/survey-utils/page-info";
import {
  GridCell,
  IHomeLocation,
  IPlanogramLocationsResponse,
  RestructuredLocationData,
  planogramLocationsResponseSchema,
} from "./types";

const LOCALSTORAGE_API_KEY_NAME = "minted-upc-picker-api-key";

export function getGridDimensions(locationData: RestructuredLocationData) {
  const baseCompareAsciiCode = 64;
  let numRows = 0;
  let maxRowLetter = null;
  let numColumns = 0;

  for (const locationName in locationData) {
    const columnNumber = parseInt(locationName.slice(1));
    if (columnNumber > numColumns) {
      numColumns = columnNumber;
    }

    const rowLetter = locationName[0];
    const asciiValueDifference = rowLetter.charCodeAt(0) - baseCompareAsciiCode;
    if (asciiValueDifference > numRows) {
      numRows = asciiValueDifference;
      maxRowLetter = rowLetter;
    }
  }

  if (maxRowLetter === null) {
    throw new Error("max row letter is null");
  }

  return [numRows, maxRowLetter, numColumns] as const;
}

export function buildGridCells(
  locationData: RestructuredLocationData,
  numColumns: number,
  maxRowLetter: string,
  horizontalSectionThresholds: Set<string>,
): GridCell[] {
  const cells: GridCell[] = [];

  for (
    let columnNumber = 1, rowLetter = "A";
    columnNumber <= numColumns && rowLetter <= maxRowLetter;
    ++columnNumber
  ) {
    cells.push(
      createGridCell(
        rowLetter,
        columnNumber,
        numColumns,
        locationData,
        horizontalSectionThresholds,
      ),
    );

    if (columnNumber === numColumns) {
      rowLetter = getNextAlphabetChar(rowLetter);
      columnNumber = 0;
    }
  }

  return cells;
}

function createGridCell(
  rowLetter: string,
  columnNumber: number,
  numColumns: number,
  locationData: RestructuredLocationData,
  horizontalSectionThresholds: Set<string>,
): GridCell {
  const locationName = `${rowLetter}${columnNumber}`;
  const products = locationData[locationName];

  return {
    locationName,
    isDisabled: products === undefined,
    hasSectionGapRight: columnNumber % 8 === 0 && columnNumber !== numColumns,
    hasSectionGapBottom: horizontalSectionThresholds.has(rowLetter),
    upcs: products?.map((product) => product.upc) ?? [],
  };
}

function getNextAlphabetChar(char: string): string {
  return String.fromCharCode(char.charCodeAt(0) + 1);
}

export function restructurePlano(homeLocations: IHomeLocation[]): RestructuredLocationData {
  const locationData = {} as RestructuredLocationData;
  homeLocations.forEach((location) => {
    locationData[location.name] = location.products;
  });

  return locationData;
}

export async function fetchLocations(pogName: string): Promise<IPlanogramLocationsResponse> {
  const apiKey = localStorage.getItem(LOCALSTORAGE_API_KEY_NAME);
  if (apiKey === null) {
    throw new Error(
      `API key could not be retrieved from local storage key: ${LOCALSTORAGE_API_KEY_NAME}`,
    );
  }

  const endpointUrl = new URL(
    "https://inventory-manager.mmonj.com/product_locator/api/get_planogram_locations/",
  );
  endpointUrl.searchParams.append("planogram-name", pogName);
  endpointUrl.searchParams.append("store-name", getStoreName().toUpperCase());

  const requestOptions = {
    method: "GET",
    headers: { Authorization: `Token ${apiKey}` },
  };

  const result = await fetchApi(endpointUrl.href, requestOptions);
  if (!result.ok) {
    throw new Error(result.error);
  }

  return planogramLocationsResponseSchema.parse(result.data);
}
