CREATE TABLE users (
    id UUID PRIMARY KEY,
    email TEXT NOT NULL UNIQUE,
    display_name TEXT,
    password_hash TEXT,
    disabled BOOL NOT NULL DEFAULT false,
    super_admin BOOL NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL,
    updated_at TIMESTAMPTZ NOT NULL
);

CREATE TABLE roles (
    id UUID PRIMARY KEY,
    name TEXT NOT NULL UNIQUE,
    description TEXT,
    created_at TIMESTAMPTZ NOT NULL
);

CREATE TABLE role_permissions (
    role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
    permission TEXT NOT NULL,
    created_at TIMESTAMPTZ NOT NULL,
    PRIMARY KEY (role_id, permission)
);

CREATE TABLE memberships (
    id UUID PRIMARY KEY,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    scope_type TEXT NOT NULL,
    scope_id TEXT NOT NULL,
    role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
    created_at TIMESTAMPTZ NOT NULL,
    UNIQUE (user_id, scope_type, scope_id)
);

CREATE TABLE sessions (
    id UUID PRIMARY KEY,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    token_hash TEXT NOT NULL UNIQUE,
    expires_at TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ NOT NULL,
    last_seen_at TIMESTAMPTZ NOT NULL,
    user_agent TEXT,
    ip TEXT
);

CREATE INDEX sessions_user_id_idx ON sessions (user_id);
CREATE INDEX sessions_expires_at_idx ON sessions (expires_at);

CREATE TABLE control_planes (
    id UUID PRIMARY KEY,
    name TEXT NOT NULL UNIQUE,
    base_url TEXT NOT NULL,
    admin_token TEXT,
    region TEXT,
    created_at TIMESTAMPTZ NOT NULL,
    updated_at TIMESTAMPTZ NOT NULL
);

CREATE TABLE networks (
    id UUID PRIMARY KEY,
    control_plane_id UUID NOT NULL REFERENCES control_planes(id) ON DELETE CASCADE,
    network_id TEXT NOT NULL,
    name TEXT NOT NULL,
    dns_domain TEXT,
    overlay_v4 TEXT,
    overlay_v6 TEXT,
    requires_approval BOOL NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL,
    updated_at TIMESTAMPTZ NOT NULL,
    UNIQUE (control_plane_id, network_id)
);

CREATE INDEX networks_control_plane_idx ON networks (control_plane_id);

CREATE TABLE audit_log (
    id UUID PRIMARY KEY,
    actor_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
    action TEXT NOT NULL,
    target_type TEXT,
    target_id TEXT,
    metadata JSONB,
    created_at TIMESTAMPTZ NOT NULL
);

CREATE INDEX audit_log_created_at_idx ON audit_log (created_at);

CREATE TABLE user_providers (
    id UUID PRIMARY KEY,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    provider TEXT NOT NULL,
    subject TEXT NOT NULL,
    created_at TIMESTAMPTZ NOT NULL,
    UNIQUE (provider, subject),
    UNIQUE (user_id, provider)
);

CREATE TABLE oidc_states (
    id UUID PRIMARY KEY,
    provider_id TEXT NOT NULL,
    state TEXT NOT NULL,
    nonce TEXT NOT NULL,
    verifier TEXT NOT NULL,
    redirect TEXT,
    expires_at TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ NOT NULL,
    UNIQUE (provider_id, state)
);

CREATE INDEX oidc_states_expires_at_idx ON oidc_states (expires_at);

INSERT INTO roles (id, name, description, created_at)
VALUES
    ('00000000-0000-0000-0000-000000000001', 'owner', 'Full access', now()),
    ('00000000-0000-0000-0000-000000000002', 'admin', 'Network admin access', now()),
    ('00000000-0000-0000-0000-000000000003', 'viewer', 'Read-only access', now());

INSERT INTO role_permissions (role_id, permission, created_at)
VALUES
    ('00000000-0000-0000-0000-000000000001', 'control_planes:read', now()),
    ('00000000-0000-0000-0000-000000000001', 'control_planes:write', now()),
    ('00000000-0000-0000-0000-000000000001', 'networks:read', now()),
    ('00000000-0000-0000-0000-000000000001', 'networks:write', now()),
    ('00000000-0000-0000-0000-000000000001', 'nodes:read', now()),
    ('00000000-0000-0000-0000-000000000001', 'nodes:write', now()),
    ('00000000-0000-0000-0000-000000000001', 'tokens:write', now()),
    ('00000000-0000-0000-0000-000000000001', 'acl:read', now()),
    ('00000000-0000-0000-0000-000000000001', 'acl:write', now()),
    ('00000000-0000-0000-0000-000000000001', 'key_policy:read', now()),
    ('00000000-0000-0000-0000-000000000001', 'key_policy:write', now()),
    ('00000000-0000-0000-0000-000000000001', 'audit:read', now()),
    ('00000000-0000-0000-0000-000000000001', 'users:read', now()),
    ('00000000-0000-0000-0000-000000000001', 'users:write', now()),
    ('00000000-0000-0000-0000-000000000001', 'roles:read', now()),
    ('00000000-0000-0000-0000-000000000001', 'roles:write', now()),

    ('00000000-0000-0000-0000-000000000002', 'control_planes:read', now()),
    ('00000000-0000-0000-0000-000000000002', 'networks:read', now()),
    ('00000000-0000-0000-0000-000000000002', 'networks:write', now()),
    ('00000000-0000-0000-0000-000000000002', 'nodes:read', now()),
    ('00000000-0000-0000-0000-000000000002', 'nodes:write', now()),
    ('00000000-0000-0000-0000-000000000002', 'tokens:write', now()),
    ('00000000-0000-0000-0000-000000000002', 'acl:read', now()),
    ('00000000-0000-0000-0000-000000000002', 'acl:write', now()),
    ('00000000-0000-0000-0000-000000000002', 'key_policy:read', now()),
    ('00000000-0000-0000-0000-000000000002', 'key_policy:write', now()),
    ('00000000-0000-0000-0000-000000000002', 'audit:read', now()),
    ('00000000-0000-0000-0000-000000000002', 'users:read', now()),
    ('00000000-0000-0000-0000-000000000002', 'roles:read', now()),

    ('00000000-0000-0000-0000-000000000003', 'control_planes:read', now()),
    ('00000000-0000-0000-0000-000000000003', 'networks:read', now()),
    ('00000000-0000-0000-0000-000000000003', 'nodes:read', now()),
    ('00000000-0000-0000-0000-000000000003', 'audit:read', now()),
    ('00000000-0000-0000-0000-000000000003', 'roles:read', now());
