File size: 2,432 Bytes
7e92e00
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { UserProfile } from "@/types";
import { supabase } from './supabase';

export async function refreshTokenProfile() {
  const {data:{user}}=await supabase.auth.getUser();
  const day=new Date().toISOString().slice(0,10);
  let used=0;
  if(user){
    const {data,error}=await supabase.from('ai_daily_usage').select('tokens_used').eq('user_id',user.id).eq('day',day).maybeSingle();
    if(error) return;
    used=data?.tokens_used || 0;
  }
  localStorage.setItem(STORE_KEY,JSON.stringify({id:user?.id || 'local',plan:'free',dailyTokenLimit:DAILY_FREE,tokensUsedToday:used,lastResetDate:day}));
  window.dispatchEvent(new Event('purcar_token_update'));
}

const STORE_KEY = "purcar_user_v3";
export const DAILY_FREE = 50000; // 50k initial/daily tokens covering input + output

function todayKey(): string {
  return new Date().toISOString().split("T")[0];
}

export function getLocalUserProfile(): UserProfile {
  if (typeof window === "undefined") {
    return { id: "local", plan: "free", dailyTokenLimit: DAILY_FREE, tokensUsedToday: 0, lastResetDate: todayKey() };
  }
  try {
    const raw = localStorage.getItem(STORE_KEY);
    if (!raw) return fresh();
    const p: UserProfile = JSON.parse(raw);
    
    // Ensure existing profiles receive the full 50k token budget
    if (p.dailyTokenLimit < DAILY_FREE) {
      p.dailyTokenLimit = DAILY_FREE;
    }

    if (p.lastResetDate !== todayKey()) {
      const reset = { ...p, dailyTokenLimit: DAILY_FREE, tokensUsedToday: 0, lastResetDate: todayKey() };
      localStorage.setItem(STORE_KEY, JSON.stringify(reset));
      return reset;
    }
    return p;
  } catch {
    return fresh();
  }
}

function fresh(): UserProfile {
  const p: UserProfile = { id: "local", plan: "free", dailyTokenLimit: DAILY_FREE, tokensUsedToday: 0, lastResetDate: todayKey() };
  if (typeof window !== "undefined") localStorage.setItem(STORE_KEY, JSON.stringify(p));
  return p;
}

export function consumeTokens(count: number): { success: boolean; remaining: number } {
  void count;
  void refreshTokenProfile();
  const p=getLocalUserProfile();
  // Display cache only. Admission and charging happen atomically on the server.
  return {success:true,remaining:Math.max(0,p.dailyTokenLimit-p.tokensUsedToday)};
}

export function estimateTokenCount(text: string): number {
  // Rough BPE estimate: ~0.75 words per token
  return Math.max(1, Math.ceil(text.split(/\s+/).length * 1.33));
}