/* ============================================================
   review-links.jsx — reviewlink CRUD + token-mode fetch
   ============================================================ */

/* -- owner side: maak/lijst/verloopt een reviewlink ----------- */
async function createReviewLink(documentId, { label, permissions = 'comment', expiresInDays = null } = {}) {
  const sb = getSupabase();
  if (!sb) throw new Error('Supabase niet beschikbaar');
  const { data: { user } } = await sb.auth.getUser();
  const payload = {
    document_id: documentId,
    label: label || null,
    permissions,
    created_by: user?.id || null,
  };
  if (expiresInDays && expiresInDays > 0) {
    payload.expires_at = new Date(Date.now() + expiresInDays * 86400_000).toISOString();
  }
  const { data, error } = await sb.from('review_links').insert(payload).select().single();
  if (error) throw error;
  return data;
}

async function listReviewLinks(documentId) {
  const sb = getSupabase();
  if (!sb) return [];
  const { data, error } = await sb
    .from('review_links')
    .select('*')
    .eq('document_id', documentId)
    .order('created_at', { ascending: false });
  if (error) { console.error('listReviewLinks', error); return []; }
  return data || [];
}

async function revokeReviewLink(id) {
  const sb = getSupabase();
  if (!sb) return;
  const { error } = await sb
    .from('review_links')
    .update({ revoked_at: new Date().toISOString() })
    .eq('id', id);
  if (error) throw error;
}

async function deleteReviewLink(id) {
  const sb = getSupabase();
  if (!sb) return;
  const { error } = await sb.from('review_links').delete().eq('id', id);
  if (error) throw error;
}

function reviewLinkUrl(token) {
  const base = window.location.origin + window.location.pathname;
  return `${base}?r=${encodeURIComponent(token)}`;
}

/* -- reviewer side: fetch doc by token, register reviewer ----- */
async function getDocumentByToken(token) {
  const sb = getSupabase();
  if (!sb) return null;
  const { data, error } = await sb.rpc('get_document_by_token', { p_token: token });
  if (error) { console.error('getDocumentByToken', error); return null; }
  const row = Array.isArray(data) ? data[0] : data;
  if (!row) return null;
  // Map to same shape as docFromRow
  return {
    id: row.id,
    meta: { ...(row.meta || {}), title: row.title || (row.meta || {}).title },
    blocks: row.blocks || [],
    headingStyles: row.heading_styles || {},
    comments: (row.meta?._comments) || [],
    suggestions: (row.meta?._suggestions) || [],
    _permissions: row.permissions,
    _reviewLinkId: row.review_link_id,
    _organizationId: row.organization_id,
  };
}

async function registerReviewer(reviewLinkId, { name, org, color, fingerprint }) {
  const sb = getSupabase();
  if (!sb) throw new Error('Supabase niet beschikbaar');
  // Try to find existing by fingerprint first
  if (fingerprint) {
    const { data: existing } = await sb
      .from('reviewers')
      .select('*')
      .eq('review_link_id', reviewLinkId)
      .eq('fingerprint', fingerprint)
      .maybeSingle();
    if (existing) {
      // update last_seen + maybe name/org if changed
      await sb.from('reviewers').update({
        last_seen_at: new Date().toISOString(),
        name, org: org || null, color: color || existing.color,
      }).eq('id', existing.id);
      return { ...existing, name, org, color };
    }
  }
  const { data, error } = await sb
    .from('reviewers')
    .insert({ review_link_id: reviewLinkId, name, org: org || null, color: color || '#8b9a54', fingerprint: fingerprint || null })
    .select()
    .single();
  if (error) throw error;
  return data;
}

/* stable-ish per-browser fingerprint for reviewer identity recovery */
function getBrowserFingerprint() {
  let fp = localStorage.getItem('tender-fingerprint');
  if (!fp) {
    fp = 'fp_' + Math.random().toString(36).slice(2) + Date.now().toString(36);
    localStorage.setItem('tender-fingerprint', fp);
  }
  return fp;
}

/* -- reviewer posts comments/suggestions via supabase -------- */
async function insertReviewerComment({ documentId, reviewerId, blockId, range, text, authorName, authorColor }) {
  const sb = getSupabase();
  if (!sb) throw new Error('Supabase niet beschikbaar');
  const { data, error } = await sb.from('comments').insert({
    document_id: documentId,
    block_id: blockId,
    range_start: range?.start ?? null,
    range_end:   range?.end   ?? null,
    text,
    author_name: authorName,
    author_color: authorColor,
    author_reviewer: reviewerId,
  }).select().single();
  if (error) throw error;
  return data;
}

async function insertReviewerSuggestion({ documentId, reviewerId, blockId, range, original, proposed, authorName, authorColor }) {
  const sb = getSupabase();
  if (!sb) throw new Error('Supabase niet beschikbaar');
  const { data, error } = await sb.from('suggestions').insert({
    document_id: documentId,
    block_id: blockId,
    range_start: range?.start ?? null,
    range_end:   range?.end   ?? null,
    original, proposed,
    author_name: authorName,
    author_color: authorColor,
    author_reviewer: reviewerId,
  }).select().single();
  if (error) throw error;
  return data;
}

async function fetchRemoteComments(documentId) {
  const sb = getSupabase();
  if (!sb) return [];
  const { data, error } = await sb
    .from('comments')
    .select('*')
    .eq('document_id', documentId)
    .order('created_at', { ascending: true });
  if (error) { console.error('fetchRemoteComments', error); return []; }
  return data || [];
}

async function fetchRemoteSuggestions(documentId) {
  const sb = getSupabase();
  if (!sb) return [];
  const { data, error } = await sb
    .from('suggestions')
    .select('*')
    .eq('document_id', documentId)
    .order('created_at', { ascending: true });
  if (error) { console.error('fetchRemoteSuggestions', error); return []; }
  return data || [];
}

Object.assign(window, {
  createReviewLink, listReviewLinks, revokeReviewLink, deleteReviewLink, reviewLinkUrl,
  getDocumentByToken, registerReviewer, getBrowserFingerprint,
  insertReviewerComment, insertReviewerSuggestion,
  fetchRemoteComments, fetchRemoteSuggestions,
});
