-- =====================================================================
--  GameDev Tracker — Schéma de base de données (Supabase / PostgreSQL)
--  À exécuter UNE SEULE FOIS dans : Supabase > SQL Editor > New query
-- =====================================================================

-- ---------- Types énumérés -------------------------------------------
do $$ begin
  create type member_role as enum
    ('lead','programmer','artist','game_designer','sound','writer','qa','other');
exception when duplicate_object then null; end $$;

do $$ begin
  create type task_status as enum ('todo','in_progress','review','done');
exception when duplicate_object then null; end $$;

do $$ begin
  create type priority_level as enum ('low','medium','high','urgent');
exception when duplicate_object then null; end $$;

do $$ begin
  create type milestone_status as enum ('planned','in_progress','done');
exception when duplicate_object then null; end $$;

do $$ begin
  create type bug_severity as enum ('low','medium','high','critical');
exception when duplicate_object then null; end $$;

do $$ begin
  create type bug_status as enum ('open','in_progress','resolved','closed');
exception when duplicate_object then null; end $$;

-- ---------- Profils (étend auth.users) -------------------------------
create table if not exists public.profiles (
  id           uuid primary key references auth.users(id) on delete cascade,
  full_name    text not null default 'Membre',
  role         member_role not null default 'other',
  avatar_color text not null default '#7c5cff',
  created_at   timestamptz not null default now()
);

-- ---------- Projets --------------------------------------------------
create table if not exists public.projects (
  id          uuid primary key default gen_random_uuid(),
  name        text not null,
  description text,
  created_by  uuid references public.profiles(id) on delete set null,
  created_at  timestamptz not null default now()
);

-- ---------- Jalons (milestones) --------------------------------------
create table if not exists public.milestones (
  id          uuid primary key default gen_random_uuid(),
  project_id  uuid not null references public.projects(id) on delete cascade,
  title       text not null,
  description text,
  due_date    date,
  status      milestone_status not null default 'planned',
  created_at  timestamptz not null default now()
);

-- ---------- Tâches ---------------------------------------------------
create table if not exists public.tasks (
  id           uuid primary key default gen_random_uuid(),
  project_id   uuid not null references public.projects(id) on delete cascade,
  title        text not null,
  description  text,
  status       task_status not null default 'todo',
  priority     priority_level not null default 'medium',
  assignee_id  uuid references public.profiles(id) on delete set null,
  milestone_id uuid references public.milestones(id) on delete set null,
  due_date     date,
  position     double precision not null default 0,
  created_by   uuid references public.profiles(id) on delete set null,
  created_at   timestamptz not null default now(),
  updated_at   timestamptz not null default now()
);

-- ---------- Bugs -----------------------------------------------------
create table if not exists public.bugs (
  id          uuid primary key default gen_random_uuid(),
  project_id  uuid not null references public.projects(id) on delete cascade,
  title       text not null,
  description text,
  severity    bug_severity not null default 'medium',
  status      bug_status not null default 'open',
  priority    priority_level not null default 'medium',
  assignee_id uuid references public.profiles(id) on delete set null,
  reporter_id uuid references public.profiles(id) on delete set null,
  created_at  timestamptz not null default now(),
  updated_at  timestamptz not null default now()
);

create index if not exists idx_tasks_project on public.tasks(project_id);
create index if not exists idx_bugs_project on public.bugs(project_id);
create index if not exists idx_milestones_project on public.milestones(project_id);

-- ---------- Maj automatique de updated_at ----------------------------
create or replace function public.touch_updated_at()
returns trigger language plpgsql as $$
begin new.updated_at = now(); return new; end $$;

drop trigger if exists trg_tasks_touch on public.tasks;
create trigger trg_tasks_touch before update on public.tasks
  for each row execute function public.touch_updated_at();

drop trigger if exists trg_bugs_touch on public.bugs;
create trigger trg_bugs_touch before update on public.bugs
  for each row execute function public.touch_updated_at();

-- ---------- Création auto du profil à l'inscription ------------------
create or replace function public.handle_new_user()
returns trigger language plpgsql security definer set search_path = public as $$
begin
  insert into public.profiles (id, full_name, role)
  values (
    new.id,
    coalesce(new.raw_user_meta_data->>'full_name', split_part(new.email,'@',1)),
    coalesce((new.raw_user_meta_data->>'role')::member_role, 'other')
  )
  on conflict (id) do nothing;
  return new;
end $$;

drop trigger if exists on_auth_user_created on auth.users;
create trigger on_auth_user_created
  after insert on auth.users
  for each row execute function public.handle_new_user();

-- ---------- Sécurité (RLS) -------------------------------------------
-- Équipe privée et de confiance : tout membre connecté a accès complet.
alter table public.profiles   enable row level security;
alter table public.projects   enable row level security;
alter table public.milestones enable row level security;
alter table public.tasks      enable row level security;
alter table public.bugs       enable row level security;

do $$
declare t text;
begin
  foreach t in array array['profiles','projects','milestones','tasks','bugs'] loop
    execute format('drop policy if exists %I_all on public.%I', t, t);
    execute format(
      'create policy %I_all on public.%I for all to authenticated using (true) with check (true)',
      t, t);
  end loop;
end $$;

-- ---------- Realtime (synchro live entre membres) --------------------
do $$ begin
  alter publication supabase_realtime add table public.tasks;
exception when duplicate_object then null; end $$;
do $$ begin
  alter publication supabase_realtime add table public.bugs;
exception when duplicate_object then null; end $$;
do $$ begin
  alter publication supabase_realtime add table public.milestones;
exception when duplicate_object then null; end $$;
