import { refreshSession, getStoredSession } from './auth';

const SUPABASE_URL = 'https://hwithddwaapyhnfwcesj.supabase.co';
const SUPABASE_ANON_KEY = 'sb_publishable_fGXkh0bSrAOqSk2jWKAzSg_NJD9YPCv';

async function safeFetch(url: string, options: RequestInit = {}): Promise<Response> {
  const session = getStoredSession();
  const token = session?.access_token || SUPABASE_ANON_KEY;
  
  const headers = {
    ...options.headers,
    'apikey': SUPABASE_ANON_KEY,
    'Authorization': `Bearer ${token}`,
  };

  let response = await fetch(url, { ...options, headers });

  if (response.status === 401 && session?.refresh_token) {
    try {
      const newSession = await refreshSession(session.refresh_token);
      const newHeaders = {
        ...options.headers,
        'apikey': SUPABASE_ANON_KEY,
        'Authorization': `Bearer ${newSession.access_token}`,
      };
      response = await fetch(url, { ...options, headers: newHeaders });
    } catch (refreshError) {
      console.error('Session refresh failed:', refreshError);
    }
  }

  return response;
}

export interface ExcelRow extends Array<any> {}

export interface SyncedRow {
  data: ExcelRow;
  status?: 'pending' | 'edited' | 'synced' | 'excel';
}

export async function getAllSyncedRows(): Promise<Record<string, SyncedRow>> {
  const PAGE_SIZE = 1000;
  const result: Record<string, SyncedRow> = {};
  try {
    let offset = 0;
    // Paginate until Supabase returns fewer rows than PAGE_SIZE (no more pages).
    // Supabase REST caps a single response at 1000 rows, so we must page.
    // Safety cap at 20 pages (20k products) to avoid infinite loops.
    for (let page = 0; page < 20; page++) {
      const response = await safeFetch(
        `${SUPABASE_URL}/rest/v1/products?select=product_id,data,status&order=product_id.asc&limit=${PAGE_SIZE}&offset=${offset}`,
        { cache: 'no-store' }
      );

      if (!response.ok) {
        const errText = await response.text();
        console.error('getAllSyncedRows failed:', response.status, errText);
        return result;
      }
      const rows = await response.json();
      for (const row of rows) {
        result[row.product_id] = { data: row.data, status: row.status };
      }
      if (rows.length < PAGE_SIZE) break;
      offset += PAGE_SIZE;
    }
    return result;
  } catch (error) {
    console.error('Error fetching synced rows from Supabase:', error);
    return result;
  }
}

export async function saveRowToSupabase(articleNo: string, rowData: ExcelRow): Promise<{ success: boolean; error?: string }> {
  try {
    const response = await safeFetch(
      `${SUPABASE_URL}/rest/v1/products`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Prefer': 'resolution=merge-duplicates',
        },
        body: JSON.stringify({
          product_id: articleNo,
          data: rowData,
          status: 'edited',
          updated_at: new Date().toISOString()
        })
      }
    );

    if (!response.ok) {
      const err = await response.json().catch(() => ({}));
      return {
        success: false,
        error: `${response.status} ${response.statusText}: ${err.message || err.error_description || 'Unknown error'}`
      };
    }

    return { success: true };
  } catch (error: any) {
    console.error('Error saving to Supabase:', error);
    return { success: false, error: error.message || 'Network error' };
  }
}

export interface HistoryEntry {
  id?: string;
  product_id: string;
  article_name: string;
  old_data: ExcelRow;
  new_data: ExcelRow;
  changed_by: string;
  changed_at: string;
}

export async function saveHistoryEntry(
  productId: string,
  articleName: string,
  oldData: ExcelRow,
  newData: ExcelRow,
  changedBy: string
): Promise<{ success: boolean; error?: string }> {
  try {
    const response = await safeFetch(
      `${SUPABASE_URL}/rest/v1/products_history`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Prefer': 'return=minimal',
        },
        body: JSON.stringify({
          product_id: productId,
          article_name: articleName,
          old_data: oldData,
          new_data: newData,
          changed_by: changedBy,
          changed_at: new Date().toISOString()
        })
      }
    );

    if (!response.ok) {
      const err = await response.json().catch(() => ({}));
      return {
        success: false,
        error: `History ${response.status}: ${err.message || 'Unknown error'}`
      };
    }

    return { success: true };
  } catch (error: any) {
    console.error('Error saving history to Supabase:', error);
    return { success: false, error: error.message || 'Network error' };
  }
}

export async function getHistory(): Promise<HistoryEntry[]> {
  try {
    const response = await safeFetch(
      `${SUPABASE_URL}/rest/v1/products_history?select=*&order=changed_at.desc&limit=500`,
      { cache: 'no-store' }
    );

    if (!response.ok) {
      const errText = await response.text();
      console.error('[getHistory] Error:', response.status, errText.substring(0, 200));
      return [{
        id: 'ERROR',
        product_id: 'ERROR',
        article_name: `Failed: ${response.status} ${errText.substring(0, 200)}`,
        old_data: [],
        new_data: [],
        changed_at: new Date().toISOString(),
        changed_by: 'system'
      }];
    }
    return await response.json();
  } catch (error: any) {
    console.error('[getHistory] Exception:', error.message);
    return [{
      id: 'EXCEPTION',
      product_id: 'EXCEPTION',
      article_name: `Message: ${error.message}`,
      old_data: [],
      new_data: [],
      changed_at: new Date().toISOString(),
      changed_by: 'system'
    }];
  }
}

export async function getHistoryDataForMerge(): Promise<Record<string, ExcelRow>> {
  try {
    const response = await safeFetch(
      `${SUPABASE_URL}/rest/v1/products_history?select=product_id,new_data&order=changed_at.desc`,
      { cache: 'no-store' }
    );

    if (!response.ok) {
      console.error('[getHistoryDataForMerge] Error:', response.status);
      return {};
    }
    const entries: Array<{ product_id: string; new_data: ExcelRow }> = await response.json();
    
    const result: Record<string, ExcelRow> = {};
    const seen = new Set<string>();
    for (const entry of entries) {
      if (seen.has(entry.product_id)) continue;
      seen.add(entry.product_id);
      if (entry.new_data && entry.new_data.length > 0) {
        result[entry.product_id] = entry.new_data;
      }
    }
    return result;
  } catch (error: any) {
    console.error('[getHistoryDataForMerge] Exception:', error.message);
    return {};
  }
}

export async function deleteHistoryEntry(id: string): Promise<boolean> {
  try {
    const response = await safeFetch(
      `${SUPABASE_URL}/rest/v1/products_history?id=eq.${encodeURIComponent(String(id))}`,
      { method: 'DELETE' }
    );

    return response.ok;
  } catch (error) {
    console.error('Error deleting history from Supabase:', error);
    return false;
  }
}

export async function resetAllPendingRows(): Promise<boolean> {
  try {
    const response = await safeFetch(
      `${SUPABASE_URL}/rest/v1/products?status=eq.pending`,
      {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
          'Prefer': 'return=minimal',
        },
        body: JSON.stringify({ status: 'edited' })
      }
    );

    return response.ok;
  } catch (error) {
    console.error('Error resetting pending rows in Supabase:', error);
    return false;
  }
}
