-- AeThex Studio Initial Database Schema
-- Run this in Supabase SQL Editor to set up your database

-- Enable RLS (Row Level Security)
alter default privileges revoke execute on functions from public;

-- Create subscription tier enum
create type subscription_tier as enum ('free', 'studio', 'pro', 'enterprise');

-- ============================================
-- PROFILES TABLE
-- ============================================
create table public.profiles (
  id uuid references auth.users on delete cascade primary key,
  username text unique,
  avatar_url text,
  created_at timestamptz default now() not null,
  updated_at timestamptz default now() not null,
  subscription_tier subscription_tier default 'free' not null,
  translation_count integer default 0 not null
);

-- Enable RLS
alter table public.profiles enable row level security;

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

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

-- Auto-create profile on signup
create function public.handle_new_user()
returns trigger
language plpgsql
security definer set search_path = ''
as $$
begin
  insert into public.profiles (id, username, avatar_url)
  values (
    new.id,
    new.raw_user_meta_data ->> 'username',
    new.raw_user_meta_data ->> 'avatar_url'
  );
  return new;
end;
$$;

create trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();

-- ============================================
-- PROJECTS TABLE
-- ============================================
create table public.projects (
  id uuid default gen_random_uuid() primary key,
  user_id uuid references public.profiles(id) on delete cascade not null,
  name text not null,
  description text,
  platforms text[] default '{}' not null,
  created_at timestamptz default now() not null,
  updated_at timestamptz default now() not null,
  is_public boolean default false not null
);

-- Enable RLS
alter table public.projects enable row level security;

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

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

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

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

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

-- Indexes
create index projects_user_id_idx on public.projects(user_id);
create index projects_is_public_idx on public.projects(is_public) where is_public = true;

-- ============================================
-- FILES TABLE
-- ============================================
create table public.files (
  id uuid default gen_random_uuid() primary key,
  project_id uuid references public.projects(id) on delete cascade not null,
  name text not null,
  path text not null,
  content text,
  language text not null,
  created_at timestamptz default now() not null,
  updated_at timestamptz default now() not null,
  
  unique(project_id, path)
);

-- Enable RLS
alter table public.files enable row level security;

-- Policies
create policy "Users can view files in their projects"
  on public.files for select
  using (
    exists (
      select 1 from public.projects
      where projects.id = files.project_id
      and projects.user_id = auth.uid()
    )
  );

create policy "Users can view files in public projects"
  on public.files for select
  using (
    exists (
      select 1 from public.projects
      where projects.id = files.project_id
      and projects.is_public = true
    )
  );

create policy "Users can insert files to their projects"
  on public.files for insert
  with check (
    exists (
      select 1 from public.projects
      where projects.id = files.project_id
      and projects.user_id = auth.uid()
    )
  );

create policy "Users can update files in their projects"
  on public.files for update
  using (
    exists (
      select 1 from public.projects
      where projects.id = files.project_id
      and projects.user_id = auth.uid()
    )
  );

create policy "Users can delete files from their projects"
  on public.files for delete
  using (
    exists (
      select 1 from public.projects
      where projects.id = files.project_id
      and projects.user_id = auth.uid()
    )
  );

-- Indexes
create index files_project_id_idx on public.files(project_id);

-- ============================================
-- TRANSLATIONS TABLE
-- ============================================
create table public.translations (
  id uuid default gen_random_uuid() primary key,
  user_id uuid references public.profiles(id) on delete cascade not null,
  source_platform text not null,
  target_platform text not null,
  source_code text not null,
  translated_code text not null,
  created_at timestamptz default now() not null
);

-- Enable RLS
alter table public.translations enable row level security;

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

create policy "Users can insert their own translations"
  on public.translations for insert
  with check (auth.uid() = user_id);

-- Indexes
create index translations_user_id_idx on public.translations(user_id);
create index translations_created_at_idx on public.translations(created_at desc);

-- ============================================
-- HELPER FUNCTIONS
-- ============================================

-- Increment translation count for user
create function public.increment_translation_count(user_uuid uuid)
returns void
language plpgsql
security definer
as $$
begin
  update public.profiles
  set translation_count = translation_count + 1,
      updated_at = now()
  where id = user_uuid;
end;
$$;

-- Updated at trigger function
create function public.handle_updated_at()
returns trigger
language plpgsql
as $$
begin
  new.updated_at = now();
  return new;
end;
$$;

-- Apply updated_at triggers
create trigger set_profiles_updated_at
  before update on public.profiles
  for each row execute procedure public.handle_updated_at();

create trigger set_projects_updated_at
  before update on public.projects
  for each row execute procedure public.handle_updated_at();

create trigger set_files_updated_at
  before update on public.files
  for each row execute procedure public.handle_updated_at();
