create table if not exists public.workspace_billing_accounts (
  id uuid primary key default gen_random_uuid(),
  workspace_id uuid not null references public.workspaces (id) on delete cascade,
  plan_code text,
  billing_interval text check (billing_interval in ('monthly', 'annual', 'custom')),
  status text not null check (status in ('not_configured', 'inactive', 'active', 'past_due', 'canceled')),
  current_period_starts_at timestamptz,
  current_period_ends_at timestamptz,
  cancel_at_period_end boolean not null default false,
  canceled_at timestamptz,
  trial_ends_at timestamptz,
  external_customer_ref text,
  external_subscription_ref text,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  constraint workspace_billing_accounts_workspace_id_key unique (workspace_id),
  constraint workspace_billing_accounts_period_bounds_check check (
    (current_period_starts_at is null and current_period_ends_at is null)
    or (current_period_starts_at is not null and current_period_ends_at is not null)
  )
);

create table if not exists public.workspace_usage_periods (
  id uuid primary key default gen_random_uuid(),
  workspace_id uuid not null references public.workspaces (id) on delete cascade,
  billing_account_id uuid not null references public.workspace_billing_accounts (id) on delete cascade,
  period_starts_at timestamptz not null,
  period_ends_at timestamptz not null,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  constraint workspace_usage_periods_workspace_period_key unique (workspace_id, period_starts_at, period_ends_at),
  constraint workspace_usage_periods_bounds_check check (period_starts_at < period_ends_at)
);

create table if not exists public.workspace_usage_counters (
  id uuid primary key default gen_random_uuid(),
  usage_period_id uuid not null references public.workspace_usage_periods (id) on delete cascade,
  workspace_id uuid not null references public.workspaces (id) on delete cascade,
  resource text not null check (resource in ('research_credits', 'exports', 'enrichments', 'api_requests')),
  consumed_quantity integer not null default 0 check (consumed_quantity >= 0),
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  constraint workspace_usage_counters_period_resource_key unique (usage_period_id, resource)
);

create table if not exists public.workspace_addon_purchases (
  id uuid primary key default gen_random_uuid(),
  workspace_id uuid not null references public.workspaces (id) on delete cascade,
  addon_code text not null check (addon_code in ('export_pack_10k', 'export_pack_50k', 'enrichment_pack_1k', 'ai_assistant_monthly', 'white_label_monthly')),
  resource text not null check (resource in ('research_credits', 'exports', 'enrichments', 'api_requests')),
  purchased_quantity integer not null check (purchased_quantity >= 0),
  remaining_quantity integer not null check (remaining_quantity >= 0),
  purchased_at timestamptz not null default now(),
  expires_at timestamptz,
  external_purchase_ref text,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create table if not exists public.workspace_addon_balances (
  id uuid primary key default gen_random_uuid(),
  workspace_id uuid not null references public.workspaces (id) on delete cascade,
  addon_code text not null check (addon_code in ('export_pack_10k', 'export_pack_50k', 'enrichment_pack_1k', 'ai_assistant_monthly', 'white_label_monthly')),
  resource text not null check (resource in ('research_credits', 'exports', 'enrichments', 'api_requests')),
  remaining_quantity integer not null default 0 check (remaining_quantity >= 0),
  expires_at timestamptz,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  constraint workspace_addon_balances_workspace_addon_resource_key unique (workspace_id, addon_code, resource)
);

create index if not exists workspace_billing_accounts_status_idx on public.workspace_billing_accounts (status);
create index if not exists workspace_billing_accounts_plan_code_idx on public.workspace_billing_accounts (plan_code);
create index if not exists workspace_usage_periods_workspace_id_idx on public.workspace_usage_periods (workspace_id);
create index if not exists workspace_usage_counters_workspace_id_idx on public.workspace_usage_counters (workspace_id);
create index if not exists workspace_addon_purchases_workspace_id_idx on public.workspace_addon_purchases (workspace_id);
create index if not exists workspace_addon_balances_workspace_id_idx on public.workspace_addon_balances (workspace_id);

drop trigger if exists set_workspace_billing_accounts_updated_at on public.workspace_billing_accounts;
create trigger set_workspace_billing_accounts_updated_at
before update on public.workspace_billing_accounts
for each row
execute function public.set_updated_at();

drop trigger if exists set_workspace_usage_periods_updated_at on public.workspace_usage_periods;
create trigger set_workspace_usage_periods_updated_at
before update on public.workspace_usage_periods
for each row
execute function public.set_updated_at();

drop trigger if exists set_workspace_usage_counters_updated_at on public.workspace_usage_counters;
create trigger set_workspace_usage_counters_updated_at
before update on public.workspace_usage_counters
for each row
execute function public.set_updated_at();

drop trigger if exists set_workspace_addon_purchases_updated_at on public.workspace_addon_purchases;
create trigger set_workspace_addon_purchases_updated_at
before update on public.workspace_addon_purchases
for each row
execute function public.set_updated_at();

drop trigger if exists set_workspace_addon_balances_updated_at on public.workspace_addon_balances;
create trigger set_workspace_addon_balances_updated_at
before update on public.workspace_addon_balances
for each row
execute function public.set_updated_at();

insert into public.workspace_billing_accounts (
  workspace_id,
  plan_code,
  billing_interval,
  status,
  current_period_starts_at,
  current_period_ends_at
)
select w.id, 'starter_monthly', 'monthly', 'active', now(), now() + interval '1 month'
from public.workspaces w
where not exists (
  select 1
  from public.workspace_billing_accounts billing
  where billing.workspace_id = w.id
);

update public.workspace_billing_accounts
set
  plan_code = 'starter_monthly',
  billing_interval = 'monthly',
  status = 'active',
  current_period_starts_at = coalesce(current_period_starts_at, now()),
  current_period_ends_at = coalesce(current_period_ends_at, now() + interval '1 month')
where plan_code is null and status = 'not_configured';
