-- ASA Foundation: RBAC — user_roles table
-- Canonical built-in roles: owner, admin, support
-- Guards check PERMISSIONS, not role strings directly.

-- Role definitions (canonical, versioned with module)
CREATE TABLE IF NOT EXISTS public.roles (
  id TEXT PRIMARY KEY,
  display_name TEXT NOT NULL,
  description TEXT,
  is_builtin BOOLEAN NOT NULL DEFAULT false,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Seed built-in roles
INSERT INTO public.roles (id, display_name, description, is_builtin) VALUES
  ('owner', 'Owner', 'Full access. Can manage all users, billing, and settings.', true),
  ('admin', 'Admin', 'Can manage users and content. Cannot change billing or transfer ownership.', true),
  ('support', 'Support', 'Can view users and impersonate for debugging. Read-only admin access.', true)
ON CONFLICT (id) DO NOTHING;

-- Permission definitions
CREATE TABLE IF NOT EXISTS public.permissions (
  id TEXT PRIMARY KEY,
  description TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Seed default permissions
INSERT INTO public.permissions (id, description) VALUES
  ('admin.access', 'Access admin panel'),
  ('admin.users.list', 'View user list'),
  ('admin.users.edit', 'Edit user details'),
  ('admin.users.delete', 'Delete users'),
  ('admin.roles.assign', 'Assign roles to users'),
  ('admin.impersonate', 'Impersonate users'),
  ('admin.audit.view', 'View audit log'),
  ('admin.billing.manage', 'Manage billing and plans'),
  ('admin.settings.edit', 'Edit application settings')
ON CONFLICT (id) DO NOTHING;

-- Role-permission mapping
CREATE TABLE IF NOT EXISTS public.role_permissions (
  role_id TEXT NOT NULL REFERENCES public.roles(id) ON DELETE CASCADE,
  permission_id TEXT NOT NULL REFERENCES public.permissions(id) ON DELETE CASCADE,
  PRIMARY KEY (role_id, permission_id)
);

-- Seed role-permission mappings
INSERT INTO public.role_permissions (role_id, permission_id) VALUES
  -- Owner: everything
  ('owner', 'admin.access'),
  ('owner', 'admin.users.list'),
  ('owner', 'admin.users.edit'),
  ('owner', 'admin.users.delete'),
  ('owner', 'admin.roles.assign'),
  ('owner', 'admin.impersonate'),
  ('owner', 'admin.audit.view'),
  ('owner', 'admin.billing.manage'),
  ('owner', 'admin.settings.edit'),
  -- Admin: users + content, no billing
  ('admin', 'admin.access'),
  ('admin', 'admin.users.list'),
  ('admin', 'admin.users.edit'),
  ('admin', 'admin.roles.assign'),
  ('admin', 'admin.impersonate'),
  ('admin', 'admin.audit.view'),
  -- Support: read-only + impersonate
  ('support', 'admin.access'),
  ('support', 'admin.users.list'),
  ('support', 'admin.impersonate'),
  ('support', 'admin.audit.view')
ON CONFLICT DO NOTHING;

-- User-role assignment (links profiles to roles)
CREATE TABLE IF NOT EXISTS public.user_roles (
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  role_id TEXT NOT NULL REFERENCES public.roles(id) ON DELETE CASCADE,
  assigned_by UUID REFERENCES auth.users(id),
  assigned_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  PRIMARY KEY (user_id, role_id)
);

-- Index for quick role lookups
CREATE INDEX IF NOT EXISTS idx_user_roles_user ON public.user_roles (user_id);
CREATE INDEX IF NOT EXISTS idx_user_roles_role ON public.user_roles (role_id);

-- RLS
ALTER TABLE public.roles ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.permissions ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.role_permissions ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.user_roles ENABLE ROW LEVEL SECURITY;

-- Roles/permissions are readable by authenticated users
CREATE POLICY "Roles are viewable by authenticated users"
  ON public.roles FOR SELECT TO authenticated USING (true);

CREATE POLICY "Permissions are viewable by authenticated users"
  ON public.permissions FOR SELECT TO authenticated USING (true);

CREATE POLICY "Role permissions are viewable by authenticated users"
  ON public.role_permissions FOR SELECT TO authenticated USING (true);

-- User roles: users can see their own roles, admins can see all
CREATE POLICY "Users can view own roles"
  ON public.user_roles FOR SELECT TO authenticated
  USING (user_id = auth.uid());

-- Add role column to profiles if it doesn't exist (backward compat with auth-basic)
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.columns
    WHERE table_schema = 'public' AND table_name = 'profiles' AND column_name = 'role'
  ) THEN
    ALTER TABLE public.profiles ADD COLUMN role TEXT DEFAULT 'user';
  END IF;
END $$;
