import {activeCustomerSession} from '@/lib/customer-auth';
import {AuthError, authFailure} from '@/lib/customer-auth';
import {db, env, json, sameOrigin} from '@/lib/server';
import {MAX_PHOTO_BYTES, PHOTO_BUCKET, photoType, photoTypes, ownPhotoPath} from '@/lib/profile-photo';

async function session(request:Request){const state=await activeCustomerSession(request);return state;}


async function storage(path: string, token: string, init: RequestInit = {}) {
  return fetch(`${env('SUPABASE_URL').replace(/\/$/, '')}/storage/v1/${path}`, {
    ...init, cache: 'no-store', signal: AbortSignal.timeout(15000),
    headers: {apikey: env('SUPABASE_PUBLISHABLE_KEY'), Authorization: `Bearer ${token}`, ...init.headers},
  });
}

async function rpc(name: string, body: unknown, token: string) {
  const response = await db(`rpc/${name}`, {method: 'POST', body: JSON.stringify(body)}, token);
  if (!response.ok) throw new AuthError('ذخیره یا دریافت عکس انجام نشد. دوباره تلاش کنید.', 503);
  return await response.json() as {path: string | null; previous_path?: string | null};
}

async function boundedBytes(body: ReadableStream<Uint8Array> | null) {
  if (!body) throw new AuthError('فایل عکس را انتخاب کنید.');
  const reader = body.getReader(), chunks: Uint8Array[] = [];
  let length = 0;
  try {
    while (true) {
      const {done, value} = await reader.read();
      if (done) break;
      length += value.byteLength;
      if (length > MAX_PHOTO_BYTES) { await reader.cancel(); throw new AuthError('حجم عکس باید کمتر از ۲ مگابایت باشد.', 413); }
      chunks.push(value);
    }
  } finally { reader.releaseLock(); }
  const bytes = new Uint8Array(length);
  let offset = 0;
  for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.length; }
  return bytes;
}

async function remove(path: string, token: string) {
  await storage(`object/${PHOTO_BUCKET}`, token, {method: 'DELETE', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({prefixes: [path]})});
}

export async function POST(request: Request) {
  try {
    if (!sameOrigin(request)) throw new AuthError('درخواست نامعتبر است.', 403);
    const {token, userId} = await session(request);
    const declared = request.headers.get('content-type')?.split(';')[0];
    if (!photoTypes.some(type => type === declared)) throw new AuthError('فقط عکس JPG، PNG یا WebP قابل قبول است.', 415);
    if (Number(request.headers.get('content-length') || 0) > MAX_PHOTO_BYTES) throw new AuthError('حداکثر حجم عکس ۲ مگابایت است.', 413);
    const bytes = await boundedBytes(request.body), type = photoType(bytes);
    if (!type || type !== declared) throw new AuthError('فایل عکس معتبر نیست.', 415);
    const extension = type === 'image/jpeg' ? 'jpg' : type === 'image/png' ? 'png' : 'webp';
    const path = `${userId}/${crypto.randomUUID()}.${extension}`;
    const upload = await storage(`object/${PHOTO_BUCKET}/${path}`, token, {method: 'POST', headers: {'Content-Type': type, 'x-upsert': 'false'}, body: bytes});
    if (!upload.ok) throw new AuthError('بارگذاری عکس انجام نشد. دوباره تلاش کنید.', 503);
    let saved;
    try { saved = await rpc('marketplace_avatar_set', {new_path: path}, token); }
    catch (error) {
      // A timed-out RPC may have committed. Never delete a photo still attached to the account.
      const current = await rpc('marketplace_avatar', {}, token).catch(() => null);
      if (current && current.path !== path) await remove(path, token).catch(() => {});
      if (current?.path === path) return json({ok: true, path});
      throw error;
    }
    if (ownPhotoPath(saved.previous_path, userId) && saved.previous_path !== path) await remove(saved.previous_path, token).catch(() => {});
    return json({ok: true, path});
  } catch (error) { return authFailure(error); }
}

export async function GET(request: Request) {
  try {
    const {token, userId} = await session(request);
    const requestedUser = new URL(request.url).searchParams.get('user');
    if (requestedUser && requestedUser !== userId) return json({error: 'عکس پیدا نشد.'}, 404);
    const {path} = await rpc('marketplace_avatar', {}, token);
    if (!ownPhotoPath(path, userId)) return json({error: 'عکسی ثبت نشده است.'}, 404);
    const response = await storage(`object/authenticated/${PHOTO_BUCKET}/${path}`, token);
    if (!response.ok) return json({error: 'عکس در دسترس نیست.'}, response.status === 404 ? 404 : 503);
    const bytes = await boundedBytes(response.body), type = photoType(bytes);
    if (!type) return json({error: 'عکس معتبر نیست.'}, 415);
    return new Response(bytes, {headers: {'Content-Type': type, 'Cache-Control': 'private, no-store', 'X-Content-Type-Options': 'nosniff', 'Content-Security-Policy': "default-src 'none'", 'Cross-Origin-Resource-Policy': 'same-origin'}});
  } catch (error) { return authFailure(error); }
}
