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

export const teamMemberFileUploadConfig: MulterOptions = {
  storage: diskStorage({
    destination: (req, file, cb) => {
      const location =
        file.fieldname === "profile_photo"
          ? fileStoreLocation.team_member_pic
          : fileStoreLocation.team_member_id_proof

      const uploadPath = `./public/${location}`
      createFolderIfNotExist(uploadPath)
      cb(null, uploadPath)
    },
    filename: (req, file, cb) => {
      const timestamp = Date.now()
      const ext = file.originalname.split(".").pop()
      const base = file.originalname.replace(`.${ext}`, "")

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

      const newFilename = `${sanitizedBase}-${timestamp}.${ext}`

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

      // Build paths for storage
      const location =
        file.fieldname === "profile_photo"
          ? fileStoreLocation.team_member_pic
          : fileStoreLocation.team_member_id_proof

      const localPath = path.join("./public", location, newFilename)
      const relativePath = `${location}/${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(
              `✅ Team member ${file.fieldname} uploaded to R2:`,
              r2Url,
            )
          } catch (error) {
            console.error(
              `❌ Failed to upload team member ${file.fieldname} to R2:`,
              error,
            )
          }
        })
      } else {
        // Keep file only on local storage
        ;(file as any).url = `/public/${relativePath}`
        ;(file as any).storage = "LOCAL"
        console.log(
          `✅ Team member ${file.fieldname} stored locally:`,
          (file as any).url,
        )
      }
    },
  }),
  limits: {
    fileSize: 20 * 1024 * 1024, // 20 MB max file size
  },
  fileFilter: (req, file, cb) => {
    const profilePhotoTypes = /\.(jpg|jpeg|png|webp)$/
    const idProofTypes = /\.(jpg|jpeg|png|pdf)$/

    const isProfile = file.fieldname === "profile_photo"
    const isIdProof = file.fieldname === "document_files"

    const allowed = isProfile
      ? profilePhotoTypes
      : isIdProof
        ? idProofTypes
        : null

    if (allowed && file.originalname.match(allowed)) {
      cb(null, true)
    } else {
      const allowedTypes = isProfile
        ? "jpg, jpeg, png, webp"
        : "jpg, jpeg, png, pdf"

      return cb(
        new BadRequestException({
          statusCode: code.VALIDATION,
          message: validationMessage(messageKey.invalid_file_type, {
            file_types: allowedTypes,
          }),
        }),
        false,
      )
    }
  },
}
