import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { NextRequest, NextResponse } from "next/server";
import { requireFamily } from "@/lib/auth";
import sharp from "sharp";
import { randomUUID } from "crypto";

const ALLOWED_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp", "image/heic"];
const MAX_BYTES = 8 * 1024 * 1024; // 8MB

/** Android often returns file.type="" or "application/octet-stream" — infer from extension. */
function resolveContentType(file: File): string {
  if (file.type && file.type !== "application/octet-stream") return file.type;
  const ext = file.name.split(".").pop()?.toLowerCase() || "";
  const map: Record<string, string> = {
    jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png",
    webp: "image/webp", heic: "image/heic",
  };
  return map[ext] || "image/jpeg";
}

function getR2Config() {
  return {
    accountId: process.env.R2_ACCOUNT_ID!,
    accessKeyId: process.env.R2_ACCESS_KEY_ID!,
    secretKey: process.env.R2_SECRET_ACCESS_KEY!,
    bucket: process.env.R2_BUCKET_NAME!,
    publicUrl: process.env.R2_PUBLIC_URL,
  };
}

function makeClient(R2: ReturnType<typeof getR2Config>) {
  return new S3Client({
    region: "auto",
    endpoint: `https://${R2.accountId}.r2.cloudflarestorage.com`,
    credentials: { accessKeyId: R2.accessKeyId, secretAccessKey: R2.secretKey },
  });
}

// POST /api/garments/upload
// Accepts multipart/form-data with a single "file" field.
// Returns { imageKey, thumbKey, imageUrl, thumbUrl }
export async function POST(req: NextRequest) {
  const auth = await requireFamily();
  if (!auth.success) return NextResponse.json({ error: auth.error }, { status: auth.status });

  // family_id comes from session — never from request params
  const familyId = auth.session!.familyId!;

  const R2 = getR2Config();
  if (!R2.accountId || !R2.accessKeyId || !R2.secretKey || !R2.bucket) {
    return NextResponse.json({ error: "R2 not configured" }, { status: 500 });
  }

  let formData: FormData;
  try {
    formData = await req.formData();
  } catch {
    return NextResponse.json({ error: "Invalid form data" }, { status: 400 });
  }

  const file = formData.get("file") as File | null;
  if (!file) return NextResponse.json({ error: "No file provided" }, { status: 400 });

  const contentType = resolveContentType(file);
  if (!ALLOWED_TYPES.includes(contentType)) {
    return NextResponse.json({ error: "Unsupported file type" }, { status: 400 });
  }

  if (file.size > MAX_BYTES) {
    return NextResponse.json({ error: "File too large (max 8MB)" }, { status: 400 });
  }

  const ext = file.name.split(".").pop()?.toLowerCase() || "jpg";
  const id = randomUUID();
  const imageKey = `garments/${familyId}/${id}-original.${ext}`;
  const thumbKey = `garments/${familyId}/${id}-thumb.webp`;

  const arrayBuffer = await file.arrayBuffer();
  const originalBuffer = Buffer.from(arrayBuffer);

  const thumbBuffer = await sharp(originalBuffer)
    .resize(400, 400, { fit: "inside", withoutEnlargement: true })
    .webp({ quality: 70 })
    .toBuffer();

  const client = makeClient(R2);

  await Promise.all([
    client.send(new PutObjectCommand({
      Bucket: R2.bucket,
      Key: imageKey,
      Body: originalBuffer,
      ContentType: contentType,
    })),
    client.send(new PutObjectCommand({
      Bucket: R2.bucket,
      Key: thumbKey,
      Body: thumbBuffer,
      ContentType: "image/webp",
    })),
  ]);

  // Return proxy URLs (never raw R2 pub URLs — those are blocked by Cloudflare Bot Management)
  const appUrl = process.env.NEXT_PUBLIC_APP_URL || "";
  return NextResponse.json({
    imageKey,
    thumbKey,
    imageUrl: `${appUrl}/api/img?key=${encodeURIComponent(imageKey)}`,
    thumbUrl: `${appUrl}/api/img?key=${encodeURIComponent(thumbKey)}`,
  });
}
