-- ============================================================
-- Fourge Branding Portal — Database Schema v2
-- Paste this entire file into Supabase → SQL Editor → Run
-- ============================================================

-- Companies (client companies — created and managed by team)
create table public.companies (
  id uuid default gen_random_uuid() primary key,
  name text not null,
  phone text default '',
  address text default '',
  created_at timestamptz default now() not null
);
alter table public.companies enable row level security;

-- Profiles (extends auth.users — auto-created on signup)
create table public.profiles (
  id uuid references auth.users on delete cascade primary key,
  name text not null default '',
  email text default '',
  role text not null check (role in ('team', 'client')) default 'client',
  company_id uuid references public.companies(id) on delete set null,
  created_at timestamptz default now() not null
);
alter table public.profiles enable row level security;

-- Projects (belong to a company)
create table public.projects (
  id uuid default gen_random_uuid() primary key,
  company_id uuid references public.companies(id) on delete cascade not null,
  name text not null,
  description text default '',
  status text not null check (status in ('active', 'completed')) default 'active',
  created_at timestamptz default now() not null
);
alter table public.projects enable row level security;

-- Tasks (belong to a project)
create table public.tasks (
  id uuid default gen_random_uuid() primary key,
  project_id uuid references public.projects(id) on delete cascade not null,
  title text not null,
  assigned_to uuid references public.profiles(id) on delete set null,
  assigned_name text,
  status text not null check (status in ('not_started', 'in_progress', 'on_hold', 'client_review', 'client_approved')) default 'not_started',
  current_version integer default 0 not null,
  invoiced boolean default false,
  submitted_at timestamptz default now() not null,
  completed_at timestamptz
);
alter table public.tasks enable row level security;

-- Submissions (each version of a request)
create table public.submissions (
  id uuid default gen_random_uuid() primary key,
  task_id uuid references public.tasks(id) on delete cascade not null,
  version_number integer not null,
  type text not null check (type in ('initial', 'revision', 'amendment')) default 'initial',
  service_type text default '',
  deadline date,
  description text default '',
  submitted_by uuid references public.profiles(id) on delete set null,
  submitted_by_name text default '',
  submitted_at timestamptz default now() not null
);
alter table public.submissions enable row level security;

-- Submission Files
create table public.submission_files (
  id uuid default gen_random_uuid() primary key,
  submission_id uuid references public.submissions(id) on delete cascade not null,
  name text not null,
  storage_path text,
  size bigint default 0
);
alter table public.submission_files enable row level security;

-- Deliveries (work sent to client)
create table public.deliveries (
  id uuid default gen_random_uuid() primary key,
  submission_id uuid references public.submissions(id) on delete cascade not null unique,
  sent_at timestamptz default now() not null,
  sent_by text default '',
  message text default ''
);
alter table public.deliveries enable row level security;

-- Delivery Files
create table public.delivery_files (
  id uuid default gen_random_uuid() primary key,
  delivery_id uuid references public.deliveries(id) on delete cascade not null,
  name text not null,
  storage_path text,
  size bigint default 0
);
alter table public.delivery_files enable row level security;

-- Company Prices (per service type, per company)
create table public.company_prices (
  id uuid default gen_random_uuid() primary key,
  company_id uuid references public.companies(id) on delete cascade not null,
  service_type text not null,
  price numeric(10,2) default 0,
  unique(company_id, service_type)
);
alter table public.company_prices enable row level security;

-- Invoices
create table public.invoices (
  id uuid default gen_random_uuid() primary key,
  company_id uuid references public.companies(id) on delete cascade not null,
  invoice_number text not null,
  status text not null check (status in ('draft', 'sent', 'paid')) default 'draft',
  invoice_date date default current_date,
  due_date date,
  total numeric(10,2) default 0,
  notes text default '',
  created_by uuid references public.profiles(id) on delete set null,
  created_at timestamptz default now() not null
);
alter table public.invoices enable row level security;

-- Invoice Items
create table public.invoice_items (
  id uuid default gen_random_uuid() primary key,
  invoice_id uuid references public.invoices(id) on delete cascade not null,
  task_id uuid references public.tasks(id) on delete set null,
  description text not null,
  quantity numeric(10,2) default 1,
  unit_price numeric(10,2) default 0,
  created_at timestamptz default now() not null
);
alter table public.invoice_items enable row level security;

-- ============================================================
-- Helpers
-- ============================================================

create or replace function public.get_my_role()
returns text as $$
  select role from public.profiles where id = auth.uid();
$$ language sql security definer stable;

create or replace function public.get_my_company_id()
returns uuid as $$
  select company_id from public.profiles where id = auth.uid();
$$ language sql security definer stable;

-- ============================================================
-- RLS Policies
-- ============================================================

-- Companies
create policy "Team all companies" on public.companies for all using (get_my_role() = 'team');
create policy "Client reads own company" on public.companies for select using (id = get_my_company_id());

-- Profiles
create policy "Own profile select" on public.profiles for select using (id = auth.uid());
create policy "Team reads all profiles" on public.profiles for select using (get_my_role() = 'team');
create policy "Own profile update" on public.profiles for update using (id = auth.uid());
create policy "Team update profiles" on public.profiles for update using (get_my_role() = 'team');

-- Projects
create policy "Team all projects" on public.projects for all using (get_my_role() = 'team');
create policy "Client reads company projects" on public.projects for select using (company_id = get_my_company_id());
create policy "Client inserts company projects" on public.projects for insert with check (company_id = get_my_company_id());

-- Tasks
create policy "Team all tasks" on public.tasks for all using (get_my_role() = 'team');
create policy "Client reads company tasks" on public.tasks for select using (
  project_id in (select id from public.projects where company_id = get_my_company_id())
);
create policy "Client insert task" on public.tasks for insert with check (
  project_id in (select id from public.projects where company_id = get_my_company_id())
);
create policy "Client updates company tasks" on public.tasks for update using (
  project_id in (select id from public.projects where company_id = get_my_company_id())
);

-- Submissions
create policy "Team all submissions" on public.submissions for all using (get_my_role() = 'team');
create policy "Client reads company submissions" on public.submissions for select using (
  task_id in (
    select t.id from public.tasks t
    join public.projects p on p.id = t.project_id
    where p.company_id = get_my_company_id()
  )
);
create policy "Client inserts submissions" on public.submissions for insert with check (submitted_by = auth.uid());

-- Submission Files
create policy "Team all submission_files" on public.submission_files for all using (get_my_role() = 'team');
create policy "Client reads company submission_files" on public.submission_files for select using (
  submission_id in (
    select s.id from public.submissions s
    join public.tasks t on t.id = s.task_id
    join public.projects p on p.id = t.project_id
    where p.company_id = get_my_company_id()
  )
);
create policy "Client inserts submission_files" on public.submission_files for insert with check (true);

-- Deliveries
create policy "Team all deliveries" on public.deliveries for all using (get_my_role() = 'team');
create policy "Client reads company deliveries" on public.deliveries for select using (
  submission_id in (
    select s.id from public.submissions s
    join public.tasks t on t.id = s.task_id
    join public.projects p on p.id = t.project_id
    where p.company_id = get_my_company_id()
  )
);

-- Delivery Files
create policy "Team all delivery_files" on public.delivery_files for all using (get_my_role() = 'team');
create policy "Client reads company delivery_files" on public.delivery_files for select using (
  delivery_id in (
    select d.id from public.deliveries d
    join public.submissions s on s.id = d.submission_id
    join public.tasks t on t.id = s.task_id
    join public.projects p on p.id = t.project_id
    where p.company_id = get_my_company_id()
  )
);

-- Company Prices
create policy "Team all company_prices" on public.company_prices for all using (get_my_role() = 'team');
create policy "Client reads own company prices" on public.company_prices for select using (company_id = get_my_company_id());

-- Invoices
create policy "Team all invoices" on public.invoices for all using (get_my_role() = 'team');
create policy "Client reads company invoices" on public.invoices for select using (company_id = get_my_company_id());

-- Invoice Items
create policy "Team all invoice_items" on public.invoice_items for all using (get_my_role() = 'team');
create policy "Client reads company invoice_items" on public.invoice_items for select using (
  invoice_id in (select id from public.invoices where company_id = get_my_company_id())
);

-- ============================================================
-- Storage Buckets
-- ============================================================
insert into storage.buckets (id, name, public) values ('submissions', 'submissions', false);
insert into storage.buckets (id, name, public) values ('deliveries', 'deliveries', false);

create policy "Auth users upload to submissions" on storage.objects
  for insert to authenticated with check (bucket_id = 'submissions');
create policy "Auth users read submissions" on storage.objects
  for select to authenticated using (bucket_id = 'submissions');

create policy "Team upload deliveries" on storage.objects
  for insert to authenticated with check (bucket_id = 'deliveries' and get_my_role() = 'team');
create policy "Auth users read deliveries" on storage.objects
  for select to authenticated using (bucket_id = 'deliveries');

-- ============================================================
-- Trigger: auto-create profile on signup
-- Team assigns company_id later via the Companies page
-- ============================================================
create or replace function public.handle_new_user()
returns trigger as $$
begin
  insert into public.profiles (id, name, email, role)
  values (
    new.id,
    coalesce(new.raw_user_meta_data->>'name', ''),
    new.email,
    coalesce(new.raw_user_meta_data->>'role', 'client')
  );
  return new;
end;
$$ language plpgsql security definer;

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