import { diskStorage } from "multer"
import { MulterOptions } from "@nestjs/platform-express/multer/interfaces/multer-options.interface"
import { BadRequestException } from "@nestjs/common"
import { code } from "../response/response.code"
import { createFolderIfNotExist, validationMessage } from "../../utils/helpers"
import { messageKey } from "../../constants/message-keys"
import { fileStoreLocation } from "./file-store-location"
import { uploadFileWithRetry } from "src/utils/uploadFile"
import path from "path"

export const incidentReportingImageConfig: MulterOptions = {
  storage: diskStorage({
    destination: (req, file, cb) => {
      const uploadPath = `./public/${fileStoreLocation.incident_reporting}`
      createFolderIfNotExist(uploadPath)
      cb(null, uploadPath)
    },

    filename: (req, file, cb) => {
      const timestamp = Date.now()
      const originalFilename = file.originalname
      const fileExtension = originalFilename.split(".").pop()
      const fileNameWithoutExtension = originalFilename.replace(
        `.${fileExtension}`,
        "",
      )
      const sanitizedFileNameWithoutExtension = fileNameWithoutExtension
        .replace(/\s+/g, "-") // Replace spaces with hyphens
        .replace(/[^a-zA-Z0-9-_.]/g, "_") // Replace special characters with underscores

      const newFilename = `${sanitizedFileNameWithoutExtension}-${timestamp}.${fileExtension}`

      // Let Multer store the file locally first
      cb(null, newFilename)

      // Use absolute path so R2 upload finds the file regardless of server cwd (e.g. PM2)
      const localPath = path.resolve(
        process.cwd(),
        "public",
        fileStoreLocation.incident_reporting,
        newFilename,
      )

      const relativePath = `${fileStoreLocation.incident_reporting}/${newFilename}`

      const strategy = process.env.FILE_UPLOAD || "LOCAL"

      if (strategy === "R2") {
        setImmediate(async () => {
          try {
            const r2Url = await uploadFileWithRetry({
              localPath,
              relativePath,
            })

            ;(file as any).url = r2Url
            ;(file as any).storage = "R2"

            console.log("✅ Incident reporting image uploaded to R2:", r2Url)
          } catch (error) {
            console.error(
              "❌ Failed to upload incident reporting image to R2:",
              error,
            )
          }
        })
      } else {
        ;(file as any).url = `/public/${relativePath}`
        ;(file as any).storage = "LOCAL"

        console.log(
          "✅ Incident reporting image stored locally:",
          (file as any).url,
        )
      }
    },
  }),

  limits: {
    fileSize: 20 * 1024 * 1024, // 20 MB
  },

  fileFilter: (req, file, cb) => {
    if (!file.originalname.match(/\.(jpg|jpeg|png|webp)$/i)) {
      return cb(
        new BadRequestException({
          statusCode: code.VALIDATION,
          message: validationMessage(messageKey.invalid_file_type, {
            file_types: "jpg, jpeg, png, webp",
          }),
        }),
        false,
      )
    }
    cb(null, true)
  },
}
