import { supabase, findOneGpi, queryGpi, insertGpi, updateGpi, deleteGpi } from '../config/supabase.js';

export { supabase, findOneGpi, queryGpi, insertGpi, updateGpi, deleteGpi };

export async function getModel(tableName: string) {
    return {
        find: async (query: any = {}) => {
            const { data, error } = await queryGpi(tableName, query);
            if (error) throw error;
            return data || [];
        },
        findOne: async (query: any) => {
            return await findOneGpi(tableName, query);
        },
        findById: async (id: string) => {
            return await findOneGpi(tableName, { id });
        },
        create: async (data: any) => {
            const result = await insertGpi(tableName, data);
            return result.data?.[0];
        },
        findOneAndUpdate: async (query: any, data: any) => {
            const existing = await findOneGpi(tableName, query);
            if (!existing) return null;
            const result = await updateGpi(tableName, existing.id, data);
            return result.data?.[0];
        },
        findByIdAndUpdate: async (id: string, data: any) => {
            const result = await updateGpi(tableName, id, data);
            return result.data?.[0];
        },
        findOneAndDelete: async (query: any) => {
            const existing = await findOneGpi(tableName, query);
            if (!existing) return null;
            await deleteGpi(tableName, existing.id);
            return existing;
        },
        countDocuments: async (query: any = {}) => {
            let q = supabase.from(tableName).select('*', { count: 'exact', head: true });
            
            if (query) {
                Object.keys(query).forEach(key => {
                    q = q.eq(key, query[key]);
                });
            }
            
            const { count, error } = await q;
            if (error) throw error;
            return count || 0;
        }
    };
}

export function getModelById(tableName: string, idField: string = 'id') {
    return {
        find: async (query: any = {}) => {
            const { data, error } = await queryGpi(tableName, { filter: query });
            if (error) throw error;
            return data || [];
        },
        findOne: async (query: any) => {
            return await findOneGpi(tableName, query);
        },
        create: async (data: any) => {
            const result = await insertGpi(tableName, data);
            return result.data?.[0];
        },
        findByIdAndUpdate: async (id: string, data: any) => {
            const result = await updateGpi(tableName, id, data);
            return result.data?.[0];
        },
        findByIdAndDelete: async (id: string) => {
            await deleteGpi(tableName, id);
            return { id };
        }
    };
}
