/*
 * -------------------------------------------------------
 * Finance / SEPA Schema
 * Phase 8: sepa_batches, sepa_items, invoices, invoice_items
 * -------------------------------------------------------
 */

create type public.sepa_batch_type as enum('direct_debit', 'credit_transfer');
create type public.sepa_batch_status as enum('draft', 'ready', 'submitted', 'executed', 'failed', 'cancelled');
create type public.sepa_item_status as enum('pending', 'success', 'failed', 'rejected');
create type public.invoice_status as enum('draft', 'sent', 'paid', 'overdue', 'cancelled', 'credited');

-- SEPA batches
create table if not exists public.sepa_batches (
  id uuid primary key default gen_random_uuid(),
  account_id uuid not null references public.accounts(id) on delete cascade,
  batch_type public.sepa_batch_type not null,
  status public.sepa_batch_status not null default 'draft',
  description text,
  execution_date date not null,
  total_amount numeric(12,2) not null default 0,
  item_count integer not null default 0,
  xml_storage_path text,
  pain_format text not null default 'pain.008.003.02',
  created_by uuid references auth.users(id) on delete set null,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);
create index ix_sepa_batches_account on public.sepa_batches(account_id);
alter table public.sepa_batches enable row level security;
revoke all on public.sepa_batches from authenticated, service_role;
grant select, insert, update, delete on public.sepa_batches to authenticated;
grant all on public.sepa_batches to service_role;
create policy sepa_batches_select on public.sepa_batches for select to authenticated using (public.has_role_on_account(account_id));
create policy sepa_batches_insert on public.sepa_batches for insert to authenticated with check (public.has_permission(auth.uid(), account_id, 'finance.sepa'::public.app_permissions));
create policy sepa_batches_update on public.sepa_batches for update to authenticated using (public.has_permission(auth.uid(), account_id, 'finance.sepa'::public.app_permissions));
create policy sepa_batches_delete on public.sepa_batches for delete to authenticated using (public.has_permission(auth.uid(), account_id, 'finance.sepa'::public.app_permissions));

-- SEPA items (individual transactions)
create table if not exists public.sepa_items (
  id uuid primary key default gen_random_uuid(),
  batch_id uuid not null references public.sepa_batches(id) on delete cascade,
  member_id uuid references public.members(id) on delete set null,
  debtor_name text not null,
  debtor_iban text not null,
  debtor_bic text,
  amount numeric(10,2) not null,
  mandate_id text,
  mandate_date date,
  remittance_info text,
  status public.sepa_item_status not null default 'pending',
  error_message text,
  created_at timestamptz not null default now()
);
create index ix_sepa_items_batch on public.sepa_items(batch_id);
create index ix_sepa_items_member on public.sepa_items(member_id);
alter table public.sepa_items enable row level security;
revoke all on public.sepa_items from authenticated, service_role;
grant select, insert, update, delete on public.sepa_items to authenticated;
grant all on public.sepa_items to service_role;
create policy sepa_items_select on public.sepa_items for select to authenticated using (exists (select 1 from public.sepa_batches b where b.id = sepa_items.batch_id and public.has_role_on_account(b.account_id)));
create policy sepa_items_mutate on public.sepa_items for all to authenticated using (exists (select 1 from public.sepa_batches b where b.id = sepa_items.batch_id and public.has_permission(auth.uid(), b.account_id, 'finance.sepa'::public.app_permissions)));

-- Invoices
create table if not exists public.invoices (
  id uuid primary key default gen_random_uuid(),
  account_id uuid not null references public.accounts(id) on delete cascade,
  invoice_number text not null,
  member_id uuid references public.members(id) on delete set null,
  recipient_name text not null,
  recipient_address text,
  issue_date date not null default current_date,
  due_date date not null,
  status public.invoice_status not null default 'draft',
  subtotal numeric(10,2) not null default 0,
  tax_rate numeric(5,2) not null default 0,
  tax_amount numeric(10,2) not null default 0,
  total_amount numeric(10,2) not null default 0,
  paid_amount numeric(10,2) not null default 0,
  paid_at timestamptz,
  notes text,
  pdf_storage_path text,
  created_by uuid references auth.users(id) on delete set null,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  unique(account_id, invoice_number)
);
create index ix_invoices_account on public.invoices(account_id);
create index ix_invoices_member on public.invoices(member_id);
create index ix_invoices_status on public.invoices(account_id, status);
alter table public.invoices enable row level security;
revoke all on public.invoices from authenticated, service_role;
grant select, insert, update, delete on public.invoices to authenticated;
grant all on public.invoices to service_role;
create policy invoices_select on public.invoices for select to authenticated using (public.has_role_on_account(account_id));
create policy invoices_insert on public.invoices for insert to authenticated with check (public.has_permission(auth.uid(), account_id, 'finance.write'::public.app_permissions));
create policy invoices_update on public.invoices for update to authenticated using (public.has_permission(auth.uid(), account_id, 'finance.write'::public.app_permissions));
create policy invoices_delete on public.invoices for delete to authenticated using (public.has_permission(auth.uid(), account_id, 'finance.write'::public.app_permissions));
create trigger trg_invoices_updated_at before update on public.invoices for each row execute function public.update_account_settings_timestamp();

-- Invoice line items
create table if not exists public.invoice_items (
  id uuid primary key default gen_random_uuid(),
  invoice_id uuid not null references public.invoices(id) on delete cascade,
  description text not null,
  quantity numeric(10,2) not null default 1,
  unit_price numeric(10,2) not null,
  total_price numeric(10,2) not null,
  sort_order integer not null default 0,
  created_at timestamptz not null default now()
);
create index ix_invoice_items_invoice on public.invoice_items(invoice_id);
alter table public.invoice_items enable row level security;
revoke all on public.invoice_items from authenticated, service_role;
grant select, insert, update, delete on public.invoice_items to authenticated;
grant all on public.invoice_items to service_role;
create policy invoice_items_select on public.invoice_items for select to authenticated using (exists (select 1 from public.invoices i where i.id = invoice_items.invoice_id and public.has_role_on_account(i.account_id)));
create policy invoice_items_mutate on public.invoice_items for all to authenticated using (exists (select 1 from public.invoices i where i.id = invoice_items.invoice_id and public.has_permission(auth.uid(), i.account_id, 'finance.write'::public.app_permissions)));
