// Notes: At the moment we take in RO Number, and ShopID. This is not very good considering the RO number can often be null, need
// to ask if it is possible that we just send the Job ID itself, this way we don't need to really care about the bodyshop, and we
// don't risk getting a null

const axios = require("axios");
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3");
const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
const { GET_JOB_BY_RO_NUMBER_AND_SHOP_ID, INSERT_NEW_DOCUMENT } = require("../../graphql-client/queries");
const { InstanceRegion } = require("../../utils/instanceMgr");
const moment = require("moment/moment");
const client = require("../../graphql-client/graphql-client").client;

const S3_BUCKET = process.env?.IMGPROXY_DESTINATION_BUCKET;

/**
 * @description VSSTA integration route
 * @type {string[]}
 */
const requiredParams = [
  "shop_id",
  "ro_nbr",
  "pdf_download_link",
  "company_api_key",
  "scan_type",
  "scan_time",
  "technician",
  "year",
  "make",
  "model"
];

const vsstaIntegrationRoute = async (req, res) => {
  const { logger } = req;

  if (!S3_BUCKET) {
    logger.log("vssta-integration-missing-bucket", "error", "api", "vssta");
    return res.status(500).json({ error: "Improper configuration" });
  }

  try {
    const missingParams = requiredParams.filter((param) => !req.body[param]);

    if (missingParams.length > 0) {
      logger.log(`vssta-integration-missing-param`, "error", "api", "vssta", {
        params: missingParams
      });

      return res.status(400).json({
        error: "Missing required parameters",
        missingParams
      });
    }

    // technician, year, make, model, is also available.
    const { shop_id, ro_nbr, pdf_download_link, scan_type, scan_time, company_api_key } = req.body;

    // 1. Get the job record by ro_number and shop_id
    const jobResult = await client.request(GET_JOB_BY_RO_NUMBER_AND_SHOP_ID, {
      roNumber: ro_nbr,
      shopId: shop_id
    });

    if (!jobResult.jobs || jobResult.jobs.length === 0) {
      logger.log(`vssta-integration-missing-ro`, "error", "api", "vssta");

      return res.status(404).json({ error: "Job not found" });
    }

    const job = jobResult.jobs[0];

    // 2. Download the base64-encoded PDF string from the provided link
    const pdfResponse = await axios.get(pdf_download_link, {
      responseType: "text", // Expect base64 string
      headers: {
        "auth-token": company_api_key
      }
    });

    // 3. Decode the base64 string to a PDF buffer
    const base64String = pdfResponse.data.replace(/^data:application\/pdf;base64,/, "");
    const pdfBuffer = Buffer.from(base64String, "base64");

    // 4. Generate key for S3
    const timestamp = moment(scan_time).tz(job.bodyshop.timezone).format("YYYYMMDD-HHmmss");
    const fileName = `${timestamp}_VSSTA_${scan_type}`;
    const s3Key = `${job.shopid}/${job.id}/${fileName.replace(/[^A-Z0-9]+/gi, "_")}.pdf`;

    // 5. Generate presigned URL for S3 upload
    const s3Client = new S3Client({ region: InstanceRegion() });

    const putCommand = new PutObjectCommand({
      Bucket: S3_BUCKET,
      Key: s3Key,
      ContentType: "application/pdf",
      StorageClass: "INTELLIGENT_TIERING"
    });

    const presignedUrl = await getSignedUrl(s3Client, putCommand, { expiresIn: 360 });

    // 6. Upload the decoded PDF to S3
    await axios.put(presignedUrl, pdfBuffer, {
      headers: { "Content-Type": "application/pdf" }
    });

    // 7. Create document record in database
    const documentMeta = {
      jobid: job.id,
      uploaded_by: "VSSTA Integration",
      name: fileName,
      key: s3Key,
      type: "application/pdf",
      extension: "pdf",
      bodyshopid: job.shopid,
      size: pdfBuffer.length,
      takenat: scan_time
    };

    const documentInsert = await client.request(INSERT_NEW_DOCUMENT, {
      docInput: [documentMeta]
    });

    if (!documentInsert.insert_documents?.returning?.length) {
      logger.log(`vssta-integration-failed-to-create-document-record`, "error", "api", "vssta", {
        params: missingParams
      });
      return res.status(500).json({ error: "Failed to create document record" });
    }

    return res.status(200).json({
      message: "VSSTA integration successful",
      documentId: documentInsert.insert_documents.returning[0].id
    });
  } catch (error) {
    logger.log(`vssta-integration-general`, "error", "api", "vssta", {
      error: error?.message,
      stack: error?.stack
    });

    return res.status(500).json({ error: error.message });
  }
};

module.exports = vsstaIntegrationRoute;
