-- Menulio initial schema (PRD §22, §21)
-- User -> Restaurant -> Location kept as separate tables from day one even
-- though V1 UX is 1:1:1, so multi-location support (V2) needs no migration.

create extension if not exists "pgcrypto";

-- ---------------------------------------------------------------------------
-- Enums
-- ---------------------------------------------------------------------------

create type subscription_status as enum ('active', 'grace_period', 'suspended', 'deleted');
create type ai_import_status as enum ('pending', 'processing', 'completed', 'failed');
create type domain_status as enum ('pending', 'verified', 'failed');

-- ---------------------------------------------------------------------------
-- Core identity
-- ---------------------------------------------------------------------------

create table users (
  id uuid primary key references auth.users (id) on delete cascade,
  full_name text,
  created_at timestamptz not null default now()
);

create table restaurants (
  id uuid primary key default gen_random_uuid(),
  name text not null,
  slug text not null unique,
  logo_url text,
  cover_url text,
  phone text,
  address text,
  created_by uuid not null references users (id) on delete restrict,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create table restaurant_members (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  user_id uuid not null references users (id) on delete cascade,
  role text not null default 'owner',
  created_at timestamptz not null default now(),
  unique (restaurant_id, user_id)
);

create table locations (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  name text not null,
  address text,
  phone text,
  created_at timestamptz not null default now()
);

-- ---------------------------------------------------------------------------
-- Menu
-- ---------------------------------------------------------------------------

create table menus (
  id uuid primary key default gen_random_uuid(),
  location_id uuid not null references locations (id) on delete cascade,
  name text not null default 'Menü',
  is_published boolean not null default false,
  published_at timestamptz,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create table menu_categories (
  id uuid primary key default gen_random_uuid(),
  menu_id uuid not null references menus (id) on delete cascade,
  name text not null,
  description text,
  sort_order integer not null default 0,
  is_active boolean not null default true,
  created_at timestamptz not null default now()
);

create table menu_items (
  id uuid primary key default gen_random_uuid(),
  category_id uuid not null references menu_categories (id) on delete cascade,
  name text not null,
  description text,
  price numeric(10, 2) not null,
  image_url text,
  sort_order integer not null default 0,
  is_active boolean not null default true,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create table menu_item_options (
  id uuid primary key default gen_random_uuid(),
  menu_item_id uuid not null references menu_items (id) on delete cascade,
  group_name text not null,
  label text not null,
  price_delta numeric(10, 2) not null default 0,
  sort_order integer not null default 0
);

-- ---------------------------------------------------------------------------
-- Theming
-- ---------------------------------------------------------------------------

create table themes (
  id uuid primary key default gen_random_uuid(),
  key text not null unique,
  name text not null,
  config jsonb not null default '{}'::jsonb
);

create table restaurant_themes (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  theme_id uuid not null references themes (id) on delete restrict,
  overrides jsonb not null default '{}'::jsonb,
  created_at timestamptz not null default now(),
  unique (restaurant_id)
);

-- ---------------------------------------------------------------------------
-- Domains & QR
-- ---------------------------------------------------------------------------

create table domains (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  hostname text not null unique,
  is_custom boolean not null default false,
  status domain_status not null default 'pending',
  verified_at timestamptz,
  created_at timestamptz not null default now()
);

create table qr_codes (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  target_url text not null,
  created_at timestamptz not null default now()
);

-- ---------------------------------------------------------------------------
-- AI import
-- ---------------------------------------------------------------------------

create table ai_imports (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  source_image text not null,
  status ai_import_status not null default 'pending',
  model text,
  raw_response jsonb,
  error text,
  processed_at timestamptz,
  created_at timestamptz not null default now()
);

create table ai_import_items (
  id uuid primary key default gen_random_uuid(),
  ai_import_id uuid not null references ai_imports (id) on delete cascade,
  category_name text,
  item_name text not null,
  description text,
  price numeric(10, 2),
  confidence numeric(4, 3),
  created_at timestamptz not null default now()
);

-- ---------------------------------------------------------------------------
-- Subscription
-- ---------------------------------------------------------------------------

create table subscriptions (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  revenuecat_entitlement text not null default 'pro',
  status subscription_status not null default 'active',
  product_id text,
  trial_ends_at timestamptz,
  current_period_ends_at timestamptz,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  unique (restaurant_id)
);

-- ---------------------------------------------------------------------------
-- Analytics & media
-- ---------------------------------------------------------------------------

create table analytics_events (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  event_type text not null,
  metadata jsonb not null default '{}'::jsonb,
  created_at timestamptz not null default now()
);

create table media (
  id uuid primary key default gen_random_uuid(),
  restaurant_id uuid not null references restaurants (id) on delete cascade,
  storage_path text not null,
  kind text not null default 'image',
  created_at timestamptz not null default now()
);

-- ---------------------------------------------------------------------------
-- Indexes
-- ---------------------------------------------------------------------------

create index on restaurant_members (user_id);
create index on locations (restaurant_id);
create index on menus (location_id);
create index on menu_categories (menu_id);
create index on menu_items (category_id);
create index on menu_item_options (menu_item_id);
create index on domains (restaurant_id);
create index on ai_imports (restaurant_id);
create index on ai_import_items (ai_import_id);
create index on analytics_events (restaurant_id, created_at);
create index on media (restaurant_id);

-- ---------------------------------------------------------------------------
-- Row Level Security
-- ---------------------------------------------------------------------------
-- Business logic lives in the API layer (PRD §23), so most tables are locked
-- to the service role. Owner-facing tables get membership-scoped policies for
-- direct client reads; public menu tables get an anon read policy scoped to
-- published menus only.

alter table users enable row level security;
alter table restaurants enable row level security;
alter table restaurant_members enable row level security;
alter table locations enable row level security;
alter table menus enable row level security;
alter table menu_categories enable row level security;
alter table menu_items enable row level security;
alter table menu_item_options enable row level security;
alter table themes enable row level security;
alter table restaurant_themes enable row level security;
alter table domains enable row level security;
alter table qr_codes enable row level security;
alter table ai_imports enable row level security;
alter table ai_import_items enable row level security;
alter table subscriptions enable row level security;
alter table analytics_events enable row level security;
alter table media enable row level security;

create policy "users read own row" on users
  for select using (id = auth.uid());

create policy "members read own restaurants" on restaurants
  for select using (
    exists (
      select 1 from restaurant_members rm
      where rm.restaurant_id = restaurants.id and rm.user_id = auth.uid()
    )
  );

create policy "members read own membership rows" on restaurant_members
  for select using (user_id = auth.uid());

create policy "anyone can read published menus" on menus
  for select using (is_published = true);

create policy "anyone can read categories of published menus" on menu_categories
  for select using (
    exists (
      select 1 from menus m where m.id = menu_categories.menu_id and m.is_published = true
    )
  );

create policy "anyone can read items of published menus" on menu_items
  for select using (
    exists (
      select 1
      from menu_categories mc
      join menus m on m.id = mc.menu_id
      where mc.id = menu_items.category_id and m.is_published = true
    )
  );

create policy "themes are public" on themes for select using (true);
