/** Service for coupon-related API calls */
import { supabase } from '@/supabase'
import type { Coupon } from '@/types'

export interface CouponFilters {
    category?: string
    is_active?: boolean
    active_only?: boolean
}

export const couponsService = {
    /** Get all coupons with optional filters */
    async getAllCoupons(filters?: CouponFilters): Promise<Coupon[]> {
        let query = supabase.from('coupons').select('*, business:businesses(*)')

        if (filters?.category) query = query.eq('category', filters.category)
        if (filters?.is_active !== undefined) query = query.eq('is_active', filters.is_active)
        if (filters?.active_only !== undefined && filters.active_only) {
            query = query.eq('is_active', true)
        }

        const { data, error } = await query
        if (error) throw new Error(error.message)
        return data as Coupon[]
    },

    /** Get a single coupon by ID */
    async getCouponById(id: string): Promise<Coupon> {
        const { data, error } = await supabase.from('coupons').select('*, business:businesses(*)').eq('id', id).single()
        if (error) throw new Error(error.message)
        return data as Coupon
    },

    /** Create a new coupon */
    async createCoupon(coupon: Omit<Coupon, 'id' | 'created_at' | 'updated_at'>): Promise<Coupon> {
        // Prevent sending nested business properties over insert
        const { business, business_name, business_address, business_phone, created_at, updated_at, id, ...payload } = coupon as any
        const { data, error } = await supabase.from('coupons').insert([payload]).select().single()
        if (error) throw new Error(error.message)
        return data as Coupon
    },

    /** Update an existing coupon */
    async updateCoupon(id: string, coupon: Partial<Coupon>): Promise<Coupon> {
        const { business, business_name, business_address, business_phone, created_at, updated_at, id: _id, ...payload } = coupon as any
        const { data, error } = await supabase.from('coupons').update(payload).eq('id', id).select().single()
        if (error) throw new Error(error.message)
        return data as Coupon
    },

    /** Delete a coupon */
    async deleteCoupon(id: string): Promise<void> {
        const { error } = await supabase.from('coupons').delete().eq('id', id)
        if (error) throw new Error(error.message)
    },

    /** Claim a coupon */
    async claimCoupon(id: string): Promise<any> {
        const { data: userData, error: userError } = await supabase.auth.getUser()
        if (userError || !userData?.user) throw new Error('User not logged in.')

        const claimPayload = {
            user_id: userData.user.id,
            coupon_id: id,
            status: 'claimed',
            redemption_code: Math.random().toString(36).substring(2, 8).toUpperCase()
        }

        const { data, error } = await supabase.from('user_coupons').insert([claimPayload]).select().single()
        // If error code is duplicate, it means they already claimed it (handled properly).
        if (error) throw error

        return data
    },

    /** Get current user's claimed coupons */
    async getMyCoupons(): Promise<any[]> {
        const { data: userData } = await supabase.auth.getUser()
        if (!userData || !userData.user) return []

        const { data, error } = await supabase
            .from('user_coupons')
            .select('*, coupon:coupons(*, business:businesses(*))')
            .eq('user_id', userData.user.id)

        if (error) throw new Error(error.message)
        return data || []
    },

    /** Validate a coupon by code (merchants/drivers only) */
    async validateCoupon(code: string): Promise<any> {
        const { data, error } = await supabase
            .from('user_coupons')
            .update({ status: 'redeemed', redeemed_at: new Date().toISOString() })
            .eq('redemption_code', code)
            .select()
            .single()

        if (error) throw new Error(error.message)
        if (!data) throw new Error('Invalid code or already redeemed.')
        return data
    }
}
