package usage

import (
	"context"

	"github.com/wangjia/pangolin/server/internal/apierr"
)

// defaultFreeDailyMinutes is the口径 fallback when the free plan row has a NULL
// daily_minutes (should not happen given the seed, but we stay safe).
const defaultFreeDailyMinutes = 10

// CheckFreeConnect enforces the free-plan connect gate and returns the user's
// remaining minutes for today (UTC).  It is called by #5's connect endpoint to
// derive the free credential's TTL.
//
// Rules:
//   - plan.ad_gate == false (pro/team): not minute-gated.  Returns Unlimited
//     when daily_minutes is NULL, otherwise the remaining minutes for the day.
//   - plan.ad_gate == true (free): today's ad_unlocked_at must be set and
//     minutes_used must be below daily_minutes (free = 10).  Returns the
//     remaining minutes; otherwise a bilingual semantic error
//     (AD_NOT_UNLOCKED / QUOTA_EXHAUSTED).
func (svc *Service) CheckFreeConnect(ctx context.Context, userID int64) (remainingMinutes int, apiErr *apierr.Error) {
	plan, err := svc.store.EffectivePlan(ctx, userID)
	if err != nil {
		return 0, apierr.ErrInternal
	}

	limit := defaultFreeDailyMinutes
	if plan.DailyMinutes.Valid {
		limit = int(plan.DailyMinutes.Int64)
	}

	// Paid plans (no ad gate).
	if !plan.AdGate {
		if !plan.DailyMinutes.Valid {
			return Unlimited, nil
		}
		day, err := svc.store.GetDay(ctx, userID, utcToday())
		if err != nil {
			return 0, apierr.ErrInternal
		}
		remaining := limit
		if day != nil {
			remaining = limit - day.MinutesUsed
		}
		if remaining < 0 {
			remaining = 0
		}
		return remaining, nil
	}

	// Free plan: require ad unlock + remaining minutes.
	day, err := svc.store.GetDay(ctx, userID, utcToday())
	if err != nil {
		return 0, apierr.ErrInternal
	}
	if day == nil || !day.AdUnlockedAt.Valid {
		return 0, apierr.ErrAdNotUnlocked
	}
	if day.MinutesUsed >= limit {
		return 0, apierr.ErrQuotaExhausted
	}
	return limit - day.MinutesUsed, nil
}
