import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import * as fs from "fs";
import * as path from "path";

const S3_ENDPOINT = process.env.S3_ENDPOINT;
const S3_REGION = process.env.S3_REGION || "fsn1";
const S3_BUCKET = process.env.S3_BUCKET;
const S3_PREFIX = process.env.S3_PREFIX;
const S3_ACCESS_KEY = process.env.S3_ACCESS_KEY;
const S3_SECRET_KEY = process.env.S3_SECRET_KEY;

if (!S3_ENDPOINT || !S3_BUCKET || !S3_ACCESS_KEY || !S3_SECRET_KEY) {
  console.error("Missing S3 credentials in environment");
  process.exit(1);
}

const s3Client = new S3Client({
  region: S3_REGION,
  endpoint: S3_ENDPOINT,
  credentials: {
    accessKeyId: S3_ACCESS_KEY,
    secretAccessKey: S3_SECRET_KEY,
  },
  forcePathStyle: true,
});

async function uploadDirectory(dirPath: string, prefix: string) {
  const files = fs.readdirSync(dirPath, { withFileTypes: true });

  for (const file of files) {
    if (file.name === ".DS_Store" || file.name === ".gitkeep") continue;

    const fullPath = path.join(dirPath, file.name);
    // Combine prefix with filename, ensuring no double slashes, e.g., mb-grid-solutions/media/filename.ext
    const s3Key = `${prefix}/${file.name}`.replace(/\/+/g, "/");

    if (file.isDirectory()) {
      await uploadDirectory(fullPath, s3Key);
    } else {
      const fileContent = fs.readFileSync(fullPath);
      let contentType = "application/octet-stream";
      if (file.name.endsWith(".png")) contentType = "image/png";
      else if (file.name.endsWith(".jpg") || file.name.endsWith(".jpeg"))
        contentType = "image/jpeg";
      else if (file.name.endsWith(".svg")) contentType = "image/svg+xml";
      else if (file.name.endsWith(".webp")) contentType = "image/webp";
      else if (file.name.endsWith(".pdf")) contentType = "application/pdf";

      try {
        await s3Client.send(
          new PutObjectCommand({
            Bucket: S3_BUCKET,
            Key: s3Key,
            Body: fileContent,
            ContentType: contentType,
            ACL: "public-read", // Hetzner requires public-read for public access usually
          }),
        );
        console.log(`✅ Uploaded ${file.name} to ${S3_BUCKET}/${s3Key}`);
      } catch (err) {
        console.error(`❌ Failed to upload ${file.name}:`, err);
      }
    }
  }
}

async function main() {
  const mediaDir = path.resolve(process.cwd(), "public/media");
  if (fs.existsSync(mediaDir)) {
    console.log("Uploading public/media...");
    // Media inside Payload CMS uses prefix/media usually, like mb-grid-solutions/media
    await uploadDirectory(mediaDir, `${S3_PREFIX}/media`);
  } else {
    console.log("No public/media directory found.");
  }

  const assetsDir = path.resolve(process.cwd(), "public/assets");
  if (fs.existsSync(assetsDir)) {
    console.log("Uploading public/assets...");
    await uploadDirectory(assetsDir, `${S3_PREFIX}/assets`);
  } else {
    console.log("No public/assets directory found.");
  }
}

main().catch(console.error);
