-- Supabase Database Schema
-- Run this SQL in your Supabase SQL Editor

-- Enable UUID extension
create extension if not exists "uuid-ossp";

-- User profiles table
create table if not exists profiles (
  id uuid references auth.users on delete cascade primary key,
  email text unique,
  full_name text,
  avatar_url text,
  is_premium boolean default true, -- Beta: all users premium
  premium_expires_at timestamp with time zone,
  tokens_remaining integer default -1, -- Beta: unlimited
  tokens_reset_at timestamp with time zone default now() + interval '24 hours',
  created_at timestamp with time zone default now(),
  updated_at timestamp with time zone default now()
);

-- Projects table (user saved code)
create table if not exists projects (
  id uuid default uuid_generate_v4() primary key,
  user_id uuid references profiles(id) on delete cascade not null,
  name text default 'Untitled Project',
  description text,
  html_code text default '',
  css_code text default '',
  js_code text default '',
  preview_url text,
  thumbnail_url text,
  is_public boolean default false,
  created_at timestamp with time zone default now(),
  updated_at timestamp with time zone default now()
);

-- AI chat messages history
create table if not exists chat_messages (
  id uuid default uuid_generate_v4() primary key,
  user_id uuid references profiles(id) on delete cascade not null,
  project_id uuid references projects(id) on delete cascade,
  role text not null check (role in ('user', 'assistant')),
  content text not null,
  tokens_used integer default 0,
  created_at timestamp with time zone default now()
);

-- Token transactions ledger
create table if not exists token_transactions (
  id uuid default uuid_generate_v4() primary key,
  user_id uuid references profiles(id) on delete cascade not null,
  transaction_type text not null check (transaction_type in ('ai_usage', 'ad_reward', 'daily_reset', 'purchase', 'premium_bonus')),
  amount integer not null,
  description text,
  created_at timestamp with time zone default now()
);

-- Subscriptions table (kept for future Stripe integration)
create table if not exists subscriptions (
  id uuid default uuid_generate_v4() primary key,
  user_id uuid references profiles(id) on delete cascade unique not null,
  status text not null check (status in ('active', 'canceled', 'past_due', 'trialing', 'beta')),
  current_period_end timestamp with time zone,
  cancel_at_period_end boolean default false,
  created_at timestamp with time zone default now(),
  updated_at timestamp with time zone default now()
);

-- Ad engagement tracking
create table if not exists ad_engagements (
  id uuid default uuid_generate_v4() primary key,
  user_id uuid references profiles(id) on delete cascade not null,
  ad_type text not null check (ad_type in ('banner', 'rewarded')),
  ad_slot text,
  reward_amount integer default 0,
  completed boolean default false,
  created_at timestamp with time zone default now()
);

-- Enable Row Level Security
alter table profiles enable row level security;
alter table projects enable row level security;
alter table chat_messages enable row level security;
alter table token_transactions enable row level security;
alter table subscriptions enable row level security;
alter table ad_engagements enable row level security;

-- RLS Policies for profiles
create policy "Users can view own profile"
  on profiles for select
  using (auth.uid() = id);

create policy "Users can update own profile"
  on profiles for update
  using (auth.uid() = id);

-- RLS Policies for projects
create policy "Users can view own projects"
  on projects for select
  using (auth.uid() = user_id);

create policy "Users can view public projects"
  on projects for select
  using (is_public = true);

create policy "Users can create projects"
  on projects for insert
  with check (auth.uid() = user_id);

create policy "Users can update own projects"
  on projects for update
  using (auth.uid() = user_id);

create policy "Users can delete own projects"
  on projects for delete
  using (auth.uid() = user_id);

-- RLS Policies for chat_messages
create policy "Users can view own messages"
  on chat_messages for select
  using (auth.uid() = user_id);

create policy "Users can create messages"
  on chat_messages for insert
  with check (auth.uid() = user_id);

-- RLS Policies for token_transactions
create policy "Users can view own transactions"
  on token_transactions for select
  using (auth.uid() = user_id);

create policy "System can create transactions"
  on token_transactions for insert
  with check (true);

-- RLS Policies for subscriptions
create policy "Users can view own subscription"
  on subscriptions for select
  using (auth.uid() = user_id);

create policy "Users can manage own subscriptions"
  on subscriptions for all
  using (auth.uid() = user_id);

-- RLS Policies for ad_engagements
create policy "Users can view own engagements"
  on ad_engagements for select
  using (auth.uid() = user_id);

create policy "System can create engagements"
  on ad_engagements for insert
  with check (true);

-- Function to handle new user creation
create or replace function public.handle_new_user()
returns trigger as $$
begin
  insert into public.profiles (id, email, full_name, avatar_url)
  values (
    new.id,
    new.email,
    new.raw_user_meta_data->>'full_name',
    new.raw_user_meta_data->>'avatar_url'
  );
  return new;
end;
$$ language plpgsql security definer;

-- Trigger for new user creation
create or replace trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();

-- Function to reset tokens daily
create or replace function reset_daily_tokens()
returns void as $$
begin
  update profiles
  set tokens_remaining = 50,
      tokens_reset_at = now() + interval '24 hours'
  where tokens_reset_at <= now()
  and is_premium = false;
end;
$$ language plpgsql security definer;

-- Indexes for performance
create index if not exists idx_projects_user_id on projects(user_id);
create index if not exists idx_projects_updated on projects(user_id, updated_at desc);
create index if not exists idx_chat_messages_user_project on chat_messages(user_id, project_id);
create index if not exists idx_token_transactions_user on token_transactions(user_id, created_at desc);
create index if not exists idx_ad_engagements_user on ad_engagements(user_id, created_at desc);
