import { mkdir, readFile, writeFile, rename, rm } from "node:fs/promises";
import path from "node:path";
import { randomUUID } from "node:crypto";
import { gallery } from "./data";
import type { GalleryItem } from "./types";
import { isSupabaseConfigured } from "./supabase/server";
import { createAdminClient } from "./supabase/admin";

export type ManagedPhoto = GalleryItem & { published: boolean; order: number };
export const galleryDirectory = () => process.env.LOCAL_GALLERY_DIR || path.join(process.cwd(), ".local-data", "gallery");
export async function listPhotos(): Promise<ManagedPhoto[]> {
  if(isSupabaseConfigured()) {
    const {data,error}=await createAdminClient().from("gallery_items").select("*").order("sort_order");
    if(error)throw new Error("Could not load gallery.");
    return (data||[]).map(x=>({id:x.id,src:x.image_url,alt:x.alt_text,category:x.category,published:x.published,order:x.sort_order}));
  }
  try{return JSON.parse(await readFile(path.join(galleryDirectory(),"photos.json"),"utf8"));}
  catch(error){if((error as NodeJS.ErrnoException).code!=="ENOENT")throw error;return gallery.map((g,i)=>({...g,published:true,order:i}));}
}
export async function changePhoto(photo:ManagedPhoto,remove=false) {
  if(isSupabaseConfigured()) {
    const db=createAdminClient();
    const result=remove?await db.from("gallery_items").delete().eq("id",photo.id):await db.from("gallery_items").upsert({id:photo.id,image_url:photo.src,alt_text:photo.alt,category:photo.category,published:photo.published,sort_order:photo.order});
    if(result.error)throw new Error("Could not save gallery."); return;
  }
  await mkdir(galleryDirectory(),{recursive:true,mode:0o700});
  const lock=path.join(galleryDirectory(),"write.lock");let acquired=false;
  for(let i=0;i<100;i++){try{await mkdir(lock);acquired=true;break;}catch(e){if((e as NodeJS.ErrnoException).code!=="EEXIST")throw e;await new Promise(r=>setTimeout(r,50));}}
  if(!acquired)throw new Error("Gallery is busy. Try again.");
  const temporary=path.join(galleryDirectory(),`${randomUUID()}.tmp`);
  try {const rows=(await listPhotos()).filter(p=>p.id!==photo.id);if(!remove)rows.push(photo);rows.sort((a,b)=>a.order-b.order);await writeFile(temporary,JSON.stringify(rows),{mode:0o600});await rename(temporary,path.join(galleryDirectory(),"photos.json"));}
  finally{await rm(temporary,{force:true});await rm(lock,{recursive:true,force:true});}
}
export async function storePhoto(bytes:Buffer) {
  const file=`${randomUUID()}.webp`;
  if(isSupabaseConfigured()) {const db=createAdminClient();const key=`gallery/${file}`;const {error}=await db.storage.from("gallery").upload(key,bytes,{contentType:"image/webp"});if(error)throw new Error("Could not upload photo.");return db.storage.from("gallery").getPublicUrl(key).data.publicUrl;}
  await mkdir(galleryDirectory(),{recursive:true,mode:0o700});await writeFile(path.join(galleryDirectory(),file),bytes,{mode:0o600});return `/api/gallery-image/${file}`;
}
