<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8" reset="true">
<cfheader name="Cache-Control" value="no-store">

<cftry>
<cfset itemsDir = expandPath("/uploads/items")>
<cfscript>
// Get ItemID from form
itemId = 0;
if (structKeyExists(form, "ItemID") && isNumeric(form.ItemID) && form.ItemID GT 0) {
  itemId = int(form.ItemID);
}

if (itemId LTE 0) {
  apiAbort({ "OK": false, "ERROR": "missing_itemid", "MESSAGE": "ItemID is required" });
}

// Fix EXIF orientation - rotate image based on EXIF Orientation tag
function fixOrientation(img) {
  try {
    exif = imageGetEXIFMetadata(img);
    if (structKeyExists(exif, "Orientation")) {
      orientation = val(exif.Orientation);
      switch(orientation) {
        case 3: imageRotate(img, 180); break;
        case 6: imageRotate(img, 90); break;
        case 8: imageRotate(img, 270); break;
        // 2,4,5,7 involve flips which are rare, skip for now
      }
    }
  } catch (any e) {
    // No EXIF or can't read it - that's fine
  }
  return img;
}

// Resize image maintaining aspect ratio, fitting within maxSize box
function resizeToFit(img, maxSize) {
  w = imageGetWidth(img);
  h = imageGetHeight(img);
  if (w <= maxSize && h <= maxSize) return img;

  if (w > h) {
    newW = maxSize;
    newH = int(h * (maxSize / w));
  } else {
    newH = maxSize;
    newW = int(w * (maxSize / h));
  }
  imageResize(img, newW, newH, "highQuality");
  return img;
}

// Create square thumbnail (center crop)
function createSquareThumb(img, size) {
  thumb = imageCopy(img, 0, 0, imageGetWidth(img), imageGetHeight(img));
  w = imageGetWidth(thumb);
  h = imageGetHeight(thumb);

  // Resize so smallest dimension equals size
  if (w > h) {
    imageResize(thumb, "", size, "highQuality");
  } else {
    imageResize(thumb, size, "", "highQuality");
  }

  // Center crop to square
  w = imageGetWidth(thumb);
  h = imageGetHeight(thumb);
  if (w > h) {
    x = int((w - h) / 2);
    imageCrop(thumb, x, 0, h, h);
  } else if (h > w) {
    y = int((h - w) / 2);
    imageCrop(thumb, 0, y, w, w);
  }

  // Final resize to exact size
  imageResize(thumb, size, size, "highQuality");
  return thumb;
}
</cfscript>

<!--- Check if file was uploaded --->
<cfif NOT structKeyExists(form, "photo") OR form.photo EQ "">
  <cfoutput>#serializeJSON({ "OK": false, "ERROR": "no_file", "MESSAGE": "No file was uploaded" })#</cfoutput>
  <cfabort>
</cfif>

<!--- Upload the file to temp location first --->
<cffile action="UPLOAD" filefield="photo" destination="#itemsDir#/" nameconflict="MAKEUNIQUE" mode="755" result="uploadResult">

<!--- Validate file type (include HEIC/HEIF for iPhone) --->
<cfset allowedExtensions = "jpg,jpeg,gif,png,webp,heic,heif">
<cfset actualExt = lCase(uploadResult.ClientFileExt)>
<cfif NOT listFindNoCase(allowedExtensions, actualExt)>
  <cffile action="DELETE" file="#itemsDir#/#uploadResult.ServerFile#">
  <cfoutput>#serializeJSON({ "OK": false, "ERROR": "invalid_type", "MESSAGE": "Only image files are accepted (jpg, jpeg, gif, png, webp, heic). Got: #actualExt#" })#</cfoutput>
  <cfabort>
</cfif>

<!--- Delete old photos and thumbnails if they exist --->
<cfscript>
for (ext in listToArray("jpg,jpeg,gif,png,webp")) {
  for (suffix in ["", "_thumb", "_medium"]) {
    oldFile = "#itemsDir#/#itemId##suffix#.#ext#";
    if (fileExists(oldFile)) {
      try { fileDelete(oldFile); } catch (any e) {}
    }
  }
}
</cfscript>

<!--- Read the uploaded image and process --->
<cfscript>
uploadedFile = "#itemsDir#/#uploadResult.ServerFile#";
img = imageNew(uploadedFile);

// Fix EXIF orientation (portrait photos appearing landscape)
img = fixOrientation(img);

// Create thumbnail (64x64 square for list view - 2x for retina)
thumb = createSquareThumb(img, 128);
thumbPath = "#itemsDir#/#itemId#_thumb.jpg";
imageWrite(thumb, thumbPath, 0.85);
fileSetAccessMode(thumbPath, "644");

// Create medium size (400px max for detail view)
medium = imageCopy(img, 0, 0, imageGetWidth(img), imageGetHeight(img));
medium = resizeToFit(medium, 400);
mediumPath = "#itemsDir#/#itemId#_medium.jpg";
imageWrite(medium, mediumPath, 0.85);
fileSetAccessMode(mediumPath, "644");

// Save full size (max 1200px to keep file sizes reasonable)
img = resizeToFit(img, 1200);
fullPath = "#itemsDir#/#itemId#.jpg";
imageWrite(img, fullPath, 0.90);
fileSetAccessMode(fullPath, "644");

// Delete the original uploaded file
try { fileDelete(uploadedFile); } catch (any e) {}

// Add cache buster
cacheBuster = dateFormat(now(), "yyyymmdd") & timeFormat(now(), "HHmmss");
</cfscript>

<!--- Return success with image URLs --->
<cfoutput>#serializeJSON({
  "OK": true,
  "ERROR": "",
  "MESSAGE": "Photo uploaded successfully",
  "IMAGEURL": "/uploads/items/#itemId#.jpg?v=#cacheBuster#",
  "THUMBURL": "/uploads/items/#itemId#_thumb.jpg?v=#cacheBuster#",
  "MEDIUMURL": "/uploads/items/#itemId#_medium.jpg?v=#cacheBuster#"
})#</cfoutput>

<cfcatch type="any">
  <cfheader statuscode="200" statustext="OK">
  <cfcontent type="application/json; charset=utf-8" reset="true">
  <cfoutput>#serializeJSON({ "OK": false, "ERROR": "server_error", "MESSAGE": cfcatch.message, "DETAIL": cfcatch.detail })#</cfoutput>
</cfcatch>
</cftry>
