const soap = require("soap");
const queries = require("../graphql-client/queries");

const CdkWsdl = require("./cdk-wsdl").default;
const logger = require("../utils/logger");

const { CDK_CREDENTIALS, CheckCdkResponseForError } = require("./cdk-wsdl");
const {
  MakeFortellisCall,
  FortellisActions,
  GetAuthToken,
  GetDepartmentId
} = require("../fortellis/fortellis-helpers");

// exports.default = async function (socket, cdk_dealerid) {
//   try {
//     CdkBase.createLogEvent(
//       socket,
//       "DEBUG",
//       `Getting makes and models list from CDK.`
//     );
//     return await GetCdkMakes(socket, cdk_dealerid);
//   } catch (error) {
//     CdkBase.createLogEvent(
//       socket,
//       "ERROR",
//       `Error encountered in CdkGetMakes. ${error}`
//     );
//   }
// };

exports.default = async function ReloadCdkMakes(req, res) {
  const { bodyshopid, cdk_dealerid } = req.body;
  try {
    //Query all CDK Models
    const newList = await GetCdkMakes(req, cdk_dealerid);

    const BearerToken = req.BearerToken;
    const client = req.userGraphQLClient;

    const deleteResult = await client
      .setHeaders({ Authorization: BearerToken })
      .request(queries.DELETE_ALL_DMS_VEHICLES, {});

    // logger.logger.debug("🚀  ~ file: cdk-get-makes.js  ~ line 53  ~ deleteResult", { deleteResult });
    //Insert the new ones.

    const insertResult = await client.setHeaders({ Authorization: BearerToken }).request(queries.INSERT_DMS_VEHICLES, {
      vehicles: newList.map((i) => {
        return {
          bodyshopid,
          makecode: i.makeCode,
          modelcode: i.modelCode,
          make: i.makeFullName,
          model: i.modelFullName
        };
      })
    });

    logger.log("cdk-replace-makes-models-success", "DEBUG", req.user.email, null, {
      cdk_dealerid,
      count: newList.length
    });

    res.sendStatus(200);
  } catch (error) {
    logger.log("cdk-replace-makes-models-error", "ERROR", req.user.email, null, {
      cdk_dealerid,
      error: {
        message: error?.message,
        stack: error?.stack,
        name: error?.name,
        code: error?.code
      }
    });
    res.status(500).json(error);
  }
};

async function GetCdkMakes(req, cdk_dealerid) {
  logger.log("cdk-replace-makes-models", "DEBUG", req.user.email, null, {
    cdk_dealerid
  });

  try {
    const soapClientVehicleInsert = await soap.createClientAsync(CdkWsdl.VehicleInsertUpdate);

    const soapResponseVehicleSearch = await soapClientVehicleInsert.getMakeModelAsync(
      {
        arg0: CDK_CREDENTIALS,
        arg1: { id: cdk_dealerid }
      },

      {}
    );

    CheckCdkResponseForError(null, soapResponseVehicleSearch);
    const [result, rawResponse, , rawRequest] = soapResponseVehicleSearch;
    logger.log("cdk-replace-makes-models-request", "ERROR", req.user.email, null, {
      cdk_dealerid,
      xml: rawRequest
    });

    logger.log("cdk-replace-makes-models-response", "ERROR", req.user.email, null, {
      cdk_dealerid,
      xml: rawResponse
    });

    return result.return;
  } catch (error) {
    logger.log("cdk-replace-makes-models-error", "ERROR", req.user.email, null, {
      cdk_dealerid,
      error: {
        message: error?.message,
        stack: error?.stack,
        name: error?.name,
        code: error?.code
      }
    });

    throw new Error(error);
  }
}

async function GetFortellisMakes(req, cdk_dealerid) {
  logger.log("fortellis-replace-makes-models", "DEBUG", req.user.email, null, {
    cdk_dealerid
  });
  try {
    const result = await MakeFortellisCall({
      ...FortellisActions.GetMakeModel,
      headers: {},
      redisHelpers: {
        setSessionTransactionData: () => {
          return null;
        },
        getSessionTransactionData: () => {
          return null;
        }
      },
      socket: { emit: () => null },
      jobid: null,
      body: {},
      debug: true,
      SubscriptionObject: {
        SubscriptionID: cdk_dealerid
      }
    });

    return result.data?.data;
  } catch (error) {
    logger.log("fortellis-replace-makes-models-error", "ERROR", req.user.email, null, {
      cdk_dealerid,
      error: {
        message: error?.message,
        stack: error?.stack,
        name: error?.name,
        code: error?.code
      }
    });

    throw new Error(error);
  }
}

async function GetFortellisCOA(req) {
  const { cdk_dealerid } = req.body;
  try {
    logger.log("fortellis-get-COA", "DEBUG", req.user?.email, null, {
      cdk_dealerid
    });
    const result = await MakeFortellisCall({
      ...FortellisActions.GetCOA,
      headers: {},
      redisHelpers: {
        setSessionTransactionData: () => {
          return null;
        },
        getSessionTransactionData: () => {
          return null;
        }
      },
      socket: { emit: () => null },
      jobid: null,
      body: {},
      debug: true,
      SubscriptionObject: {
        SubscriptionID: cdk_dealerid
      }
    });

    return result.data?.data;
  } catch (error) {
    logger.log("fortellis-get-COA-error", "ERROR", req.user?.email, null, {
      cdk_dealerid,
      error: error.message,
      stack: error.stack
    });

    throw new Error(error);
  }
}
exports.fortellisCOA = GetFortellisCOA

exports.fortellis = async function ReloadFortellisMakes(req, res) {
  const { bodyshopid, cdk_dealerid } = req.body;
  try {
    //Query all CDK Models
    const newList = await GetFortellisMakes(req, cdk_dealerid);

    const BearerToken = req.BearerToken;
    const client = req.userGraphQLClient;

    const deleteResult = await client
      .setHeaders({ Authorization: BearerToken })
      .request(queries.DELETE_ALL_DMS_VEHICLES, {});

    //Insert the new ones.


    const insertResult = await client.setHeaders({ Authorization: BearerToken }).request(queries.INSERT_DMS_VEHICLES, {
      //Below filtering is requried due to schema requirements. 
      //Does not make sense for there to be empty entries, but leaving in to prevent prod issues.
      vehicles: newList.filter(i => i.make && i.model && i.make !== '' && i.model !== '' && i.fullMakeName && i.fullModelName && i.fullMakeName !== '' && i.fullModelName !== '').map((i) => {
        return {
          bodyshopid,
          makecode: i.make,
          modelcode: i.model,
          make: i.fullMakeName,
          model: i.fullModelName
        };
      })
    });

    logger.log("fortellis-replace-makes-models-success", "DEBUG", req.user.email, null, {
      cdk_dealerid,
      count: newList.length
    });

    res.sendStatus(200);
  } catch (error) {
    logger.log("fortellis-replace-makes-models-error", "ERROR", req.user.email, null, {
      cdk_dealerid,
      error: error.message,
      stack: error.stack
    });
    res.status(500).json(error);
  }
};
