import { DBFFile } from "dbffile";
import log from "electron-log/main";
import _ from "lodash";
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
import errorTypeCheck from "../../util/errorTypeCheck";
import { DecodedStl, DecodedStlLine } from "./decode-stl.interface";
import { platform } from "@electron-toolkit/utils";
import { findFileCaseInsensitive } from "./decoder-utils";

const DecodeStl = async (
  extensionlessFilePath: string,
): Promise<DecodedStl> => {
  let dbf: DBFFile | null = null;
  if (platform.isWindows) {
    try {
      dbf = await DBFFile.open(`${extensionlessFilePath}.STL`);
    } catch (error) {
      log.error("Error opening STL File.", errorTypeCheck(error));
    }

    if (!dbf) {
      log.error(`Could not find any STL files at ${extensionlessFilePath}`);
      throw new Error(
        `Could not find any STL files at ${extensionlessFilePath}`,
      );
    }
  } else {
    const possibleExtensions: string[] = ["stl"];
    const filePath = await findFileCaseInsensitive(
      extensionlessFilePath,
      possibleExtensions,
    );
    try {
      if (!filePath) {
        log.error(`Could not find any STL files at ${extensionlessFilePath}`);
        throw new Error(
          `Could not find any STL files at ${extensionlessFilePath}`,
        );
      }
      dbf = await DBFFile.open(filePath);
    } catch (error) {
      log.error("Error opening STL File.", errorTypeCheck(error));
      throw error;
    }
  }
  const rawDBFRecord = await dbf.readRecords();

  //AD2 will always have only 1 row.
  //Commented lines have been cross referenced with existing partner fields.

  const rawStlData: DecodedStlLine[] = rawDBFRecord.map((record) => {
    const singleLineData: DecodedStlLine = deepLowerCaseKeys(
      _.pick(record, [
        //TODO: Add typings for EMS File Formats.
        "TTL_TYPE",
        "TTL_TYPECD",
        "T_AMT",
        "T_HRS",
        "T_ADDLBR",
        "T_DISCAMT",
        "T_MKUPAMT",
        "T_GDISCAMT",
        "TAX_AMT",
        "NT_AMT",
        "NT_HRS",
        "NT_ADDLBR",
        "NT_DISC",
        "NT_MKUP",
        "NT_GDIS",
        "TTL_TYPAMT",
        "TTL_HRS",
        "TTL_AMT",
      ]),
    );
    //Apply line by line adjustments.

    return singleLineData;
  });

  //Apply business logic transfomrations.
  //We don't have an inspection date, we instead have `date_estimated`

  return { cieca_stl: { data: rawStlData } };
};
export default DecodeStl;
