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 contractFileConfig: MulterOptions = {
  storage: diskStorage({
    destination: (req, file, cb) => {
      const uploadPath = `./public/${fileStoreLocation.client_contact}`
      createFolderIfNotExist(uploadPath)
      cb(null, uploadPath)
    },
    filename: (req, file, cb) => {
      const timestamp = Date.now()
      const originalFilename = file.originalname
      const fileExtension = originalFilename.split(".").pop()
      const baseName = originalFilename.replace(`.${fileExtension}`, "")

      // ✅ Sanitize filename - spaces -> hyphens, special chars -> underscores
      const sanitizedBaseName = baseName
        .replace(/\s+/g, "-") // Replace spaces with hyphens
        .replace(/[^a-zA-Z0-9-_.]/g, "_") // Replace special characters with underscores

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

      // Let Multer create the file on disk
      cb(null, newFilename)

      // Build paths for storage
      const localPath = path.join(
        "./public",
        fileStoreLocation.client_contact,
        newFilename,
      )
      const relativePath = `${fileStoreLocation.client_contact}/${newFilename}`

      // Decide storage backend based on env
      const strategy = process.env.FILE_UPLOAD || "LOCAL"

      if (strategy === "R2") {
        // Asynchronously upload to R2 and delete local file after success
        setImmediate(async () => {
          try {
            const r2Url = await uploadFileWithRetry({
              localPath,
              relativePath,
            })

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

            console.log("✅ Contract document uploaded to R2:", r2Url)
          } catch (error) {
            console.error("❌ Failed to upload contract document to R2:", error)
          }
        })
      } else {
        // Keep file only on local storage
        ;(file as any).url = `/public/${relativePath}`
        ;(file as any).storage = "LOCAL"
        console.log("✅ Contract document stored locally:", (file as any).url)
      }
    },
  }),
  limits: {
    fileSize: 20 * 1024 * 1024, // 20 MB max
  },
  fileFilter: (req, file, cb) => {
    if (!file.originalname.match(/\.(pdf|doc|docx|jpg|jpeg|png)$/)) {
      return cb(
        new BadRequestException({
          statusCode: code.VALIDATION,
          message: validationMessage(messageKey.invalid_file_type, {
            file_types: "pdf, doc, docx, jpg, jpeg, png",
          }),
        }),
        false,
      )
    }
    cb(null, true)
  },
}
