alter table if exists public.wg_gallery_photos
    add column if not exists color_family text,
    add column if not exists is_picked boolean not null default false,
    add column if not exists picked_at timestamptz,
    add column if not exists picked_by text,
    add column if not exists pick_note text,
    add column if not exists oss_bucket text,
    add column if not exists oss_object_key text,
    add column if not exists oss_url text,
    add column if not exists oss_synced_at timestamptz,
    add column if not exists oss_sync_error text;

create table if not exists public.wg_photo_collections (
    id uuid primary key default gen_random_uuid(),
    title text not null,
    slug text not null unique,
    description text,
    cover_photo_id uuid references public.wg_gallery_photos(id) on delete set null,
    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 if not exists public.wg_photo_collection_items (
    id uuid primary key default gen_random_uuid(),
    collection_id uuid not null references public.wg_photo_collections(id) on delete cascade,
    photo_id uuid not null references public.wg_gallery_photos(id) on delete cascade,
    sort_order integer not null default 0,
    created_at timestamptz not null default now(),
    unique (collection_id, photo_id)
);

create table if not exists public.wg_app_users (
    id uuid primary key default gen_random_uuid(),
    auth_user_id uuid unique references auth.users(id) on delete set null,
    email text unique,
    password_hash text,
    display_name text,
    avatar_url text,
    auth_provider text not null default 'email',
    status text not null default 'active',
    created_at timestamptz not null default now(),
    updated_at timestamptz not null default now()
);

create table if not exists public.wg_user_favorites (
    user_id uuid not null references public.wg_app_users(id) on delete cascade,
    photo_id uuid not null references public.wg_gallery_photos(id) on delete cascade,
    created_at timestamptz not null default now(),
    primary key (user_id, photo_id)
);

create table if not exists public.wg_user_settings (
    user_id uuid primary key references public.wg_app_users(id) on delete cascade,
    preferences jsonb not null default '{}'::jsonb,
    download_preferences jsonb not null default '{}'::jsonb,
    updated_at timestamptz not null default now()
);

create index if not exists wg_gallery_photos_pick_idx
    on public.wg_gallery_photos (is_picked, picked_at desc, photo_created_at desc);

create index if not exists wg_gallery_photos_color_family_idx
    on public.wg_gallery_photos (color_family);

create index if not exists wg_gallery_photos_color_idx
    on public.wg_gallery_photos (color);

create index if not exists wg_photo_collections_published_idx
    on public.wg_photo_collections (is_published, published_at desc, created_at desc);

create index if not exists wg_photo_collection_items_collection_sort_idx
    on public.wg_photo_collection_items (collection_id, sort_order, created_at);

create index if not exists wg_photo_collection_items_photo_idx
    on public.wg_photo_collection_items (photo_id);

create index if not exists wg_app_users_auth_user_idx
    on public.wg_app_users (auth_user_id);

create index if not exists wg_app_users_email_idx
    on public.wg_app_users (email);

alter table public.wg_gallery_photos enable row level security;
alter table public.wg_photo_collections enable row level security;
alter table public.wg_photo_collection_items enable row level security;
alter table public.wg_app_users enable row level security;
alter table public.wg_user_favorites enable row level security;
alter table public.wg_user_settings enable row level security;

drop policy if exists "Public can read gallery photos" on public.wg_gallery_photos;
drop policy if exists "Public can read picked gallery photos" on public.wg_gallery_photos;
create policy "Public can read picked gallery photos"
    on public.wg_gallery_photos
    for select
    to anon, authenticated
    using (is_picked = true);

drop policy if exists "Public can read published collections" on public.wg_photo_collections;
create policy "Public can read published collections"
    on public.wg_photo_collections
    for select
    to anon, authenticated
    using (is_published = true);

drop policy if exists "Public can read published collection items" on public.wg_photo_collection_items;
create policy "Public can read published collection items"
    on public.wg_photo_collection_items
    for select
    to anon, authenticated
    using (
        exists (
            select 1
            from public.wg_photo_collections collections
            where collections.id = collection_id
              and collections.is_published = true
        )
        and exists (
            select 1
            from public.wg_gallery_photos photos
            where photos.id = photo_id
              and photos.is_picked = true
        )
    );

drop policy if exists "Users can read own profile" on public.wg_app_users;
create policy "Users can read own profile"
    on public.wg_app_users
    for select
    to authenticated
    using (auth_user_id = auth.uid());

drop policy if exists "Users can update own profile" on public.wg_app_users;
create policy "Users can update own profile"
    on public.wg_app_users
    for update
    to authenticated
    using (auth_user_id = auth.uid())
    with check (auth_user_id = auth.uid());

drop policy if exists "Users can manage own favorites" on public.wg_user_favorites;
create policy "Users can manage own favorites"
    on public.wg_user_favorites
    for all
    to authenticated
    using (
        exists (
            select 1
            from public.wg_app_users users
            where users.id = user_id
              and users.auth_user_id = auth.uid()
        )
    )
    with check (
        exists (
            select 1
            from public.wg_app_users users
            where users.id = user_id
              and users.auth_user_id = auth.uid()
        )
    );

drop policy if exists "Users can manage own settings" on public.wg_user_settings;
create policy "Users can manage own settings"
    on public.wg_user_settings
    for all
    to authenticated
    using (
        exists (
            select 1
            from public.wg_app_users users
            where users.id = user_id
              and users.auth_user_id = auth.uid()
        )
    )
    with check (
        exists (
            select 1
            from public.wg_app_users users
            where users.id = user_id
              and users.auth_user_id = auth.uid()
        )
    );

grant select on table public.wg_gallery_photos to anon, authenticated;
grant select on table public.wg_photo_collections to anon, authenticated;
grant select on table public.wg_photo_collection_items to anon, authenticated;
grant select, update on table public.wg_app_users to authenticated;
grant select, insert, update, delete on table public.wg_user_favorites to authenticated;
grant select, insert, update, delete on table public.wg_user_settings to authenticated;

drop trigger if exists set_wg_photo_collections_updated_at on public.wg_photo_collections;
create trigger set_wg_photo_collections_updated_at
    before update on public.wg_photo_collections
    for each row
    execute function public.set_wg_updated_at();

drop trigger if exists set_wg_app_users_updated_at on public.wg_app_users;
create trigger set_wg_app_users_updated_at
    before update on public.wg_app_users
    for each row
    execute function public.set_wg_updated_at();

drop trigger if exists set_wg_user_settings_updated_at on public.wg_user_settings;
create trigger set_wg_user_settings_updated_at
    before update on public.wg_user_settings
    for each row
    execute function public.set_wg_updated_at();
