const axios = require("axios");
const { createObjectCsvWriter } = require("csv-writer");
const moment = require("moment");
const fs = require("fs");
const https = require("https");

const CONFIG = {
  API_URL: "https://dropship.ecomzone.eu/api/catalog",
  API_KEY: "klRyAdrXaxL0s6PEUp7LDlH6T8aPSCtBY8NiEHsHiWpc6646K2TZPi5KMxUg",
  MAX_RETRIES: 3,
  RETRY_DELAY: 10000,
  OUTPUT_DIR: "./output",
  LOG_DIR: "./logs",
};

function ensureDirectories() {
  if (!fs.existsSync(CONFIG.OUTPUT_DIR)) {
    fs.mkdirSync(CONFIG.OUTPUT_DIR);
  }
  if (!fs.existsSync(CONFIG.LOG_DIR)) {
    fs.mkdirSync(CONFIG.LOG_DIR);
  }
}

function getCsvWriter() {
  const timestamp = moment().format("YYYY-MM-DD-HH-mm-ss");
  return createObjectCsvWriter({
    path: `${CONFIG.OUTPUT_DIR}/products_${timestamp}.csv`,
    header: [
      { id: "sku", title: "Product SKU" },
      { id: "product_name", title: "Name" },
      { id: "category", title: "Category" },
      { id: "product_price", title: "Wholesale price" },
      { id: "ean", title: "EAN" },
      { id: "variation_name", title: "Variation" },
      { id: "variation_sku", title: "Variation SKU" },
      { id: "width", title: "Width" },
      { id: "height", title: "Height" },
      { id: "stock", title: "Quantity" },
      { id: "description", title: "Description" },
      { id: "image", title: "Main image" },
    ],
    fieldDelimiter: ";",
    recordDelimiter: "\n",
  });
}

function transformData(data) {
  return data.map((item) => ({
    sku: item.sku || "",
    product_name: item.product_name || "",
    category: item.category || "",
    product_price: item.product_price || "",
    ean: item.ean || "",
    variation_name: item.variation_name || "",
    variation_sku: item.variation_sku || item.sku || "",
    width: item.width || "",
    height: item.height || "",
    stock: item.stock || "0",
    description: (item.description || "").replace(/\n/g, " ").trim(),
    image: item.image || "",
  }));
}

const axiosInstance = axios.create({
  timeout: 30000, // 30 seconds timeout
  httpsAgent: new https.Agent({
    rejectUnauthorized: false, // Only use this in development
    keepAlive: true,
    keepAliveMsecs: 1000,
    maxSockets: 10,
  }),
  maxContentLength: Infinity,
  maxBodyLength: Infinity,
});

async function saveToCSV(data) {
  try {
    const csvWriter = getCsvWriter();
    await csvWriter.writeRecords(data);
    logger.log("Data successfully written to CSV");
  } catch (error) {
    logger.error(`Error writing to CSV: ${error.message}`);
    throw error;
  }
}

async function fetchDataFromAPI() {
  let retries = 0;
  while (retries < CONFIG.MAX_RETRIES) {
    try {
      logger.log(`Attempting API call (${retries + 1}/${CONFIG.MAX_RETRIES})`);

      const response = await axiosInstance({
        method: "get",
        url: CONFIG.API_URL,
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
          Authorization: `Bearer ${CONFIG.API_KEY}`,
        },
        params: {
          perpage: 1000,
        },
      });

      if (response.data && response.data.data) {
        logger.log("Data successfully retrieved from API");
        return response.data.data;
      }

      throw new Error("Invalid data structure received from API");
    } catch (error) {
      logger.error(
        `API call failed (attempt ${retries + 1}): ${error.message}`,
      );

      if (error.response) {
        logger.error(`Status: ${error.response.status}`);
        logger.error(`Response data: ${JSON.stringify(error.response.data)}`);
      }

      retries++;
      if (retries < CONFIG.MAX_RETRIES) {
        logger.log(
          `Waiting ${CONFIG.RETRY_DELAY / 1000} seconds before retry...`,
        );
        await delay(CONFIG.RETRY_DELAY);
      }
    }
  }
  throw new Error("Max retries exceeded");
}

const logger = {
  log: (message) => {
    const timestamp = moment().format("YYYY-MM-DD HH:mm:ss");
    const logMessage = `${timestamp} - ${message}\n`;
    console.log(message);
    fs.appendFileSync(`${CONFIG.LOG_DIR}/app.log`, logMessage);
  },
  error: (message) => {
    const timestamp = moment().format("YYYY-MM-DD HH:mm:ss");
    const logMessage = `${timestamp} - ERROR: ${message}\n`;
    console.error(message);
    fs.appendFileSync(`${CONFIG.LOG_DIR}/error.log`, logMessage);
  },
};

function validateData(data) {
  if (!Array.isArray(data)) {
    return [];
  }

  return data.filter((item) => {
    return (
      item &&
      typeof item.sku === "string" &&
      typeof item.product_name === "string" &&
      typeof item.product_price !== "undefined" &&
      typeof item.stock !== "undefined"
    );
  });
}

async function main() {
  try {
    ensureDirectories();
    logger.log("Starting data extraction process");

    const rawData = await fetchDataFromAPI();

    if (rawData) {
      const validatedData = validateData(rawData);
      logger.log(`Found ${validatedData.length} valid records`);

      if (validatedData.length > 0) {
        const transformedData = transformData(validatedData);
        await saveToCSV(transformedData);
        logger.log(
          `Successfully saved ${transformedData.length} records to CSV`,
        );
        logger.log("Process completed successfully");
      } else {
        logger.log("No valid data to save");
      }
    } else {
      logger.log("No data received from API");
    }
  } catch (error) {
    logger.error(`Process failed: ${error.message}`);
    process.exit(1);
  }
}

// Fix the delay function name (it was "dalay")
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

// Fix the loggerConfig function
function loggerConfig() {
  const logFile = `${CONFIG.LOG_DIR}/log-${moment().format("YYYY-MM-DD")}.log`;
  const logStream = fs.createWriteStream(logFile, { flags: "a" });
  console.log = (message) => {
    logStream.write(`[${moment().format("YYYY-MM-DD HH:mm:ss")}] ${message}\n`);
  };
}

main();
