-- Template for creating a new tenant schema
-- Replace {TENANT_ID} with actual tenant ID (e.g., t001)

CREATE SCHEMA IF NOT EXISTS it0_t_{TENANT_ID};

SET LOCAL search_path TO it0_t_{TENANT_ID};

-- Agent Sessions
CREATE TABLE agent_sessions (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    engine_type     VARCHAR(20) NOT NULL,
    status          VARCHAR(20) NOT NULL DEFAULT 'active',
    system_prompt   TEXT,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    metadata        JSONB DEFAULT '{}'
);

-- Command Records
CREATE TABLE command_records (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    session_id      UUID NOT NULL REFERENCES agent_sessions(id),
    command         TEXT NOT NULL,
    risk_level      SMALLINT NOT NULL DEFAULT 0,
    status          VARCHAR(20) NOT NULL,
    output          TEXT,
    error           TEXT,
    approved_by     UUID,
    executed_at     TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    duration_ms     INTEGER
);

CREATE INDEX idx_command_records_session ON command_records(session_id);
CREATE INDEX idx_command_records_risk ON command_records(risk_level) WHERE risk_level >= 2;

-- Ops Tasks
CREATE TABLE ops_tasks (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    type            VARCHAR(30) NOT NULL,
    title           VARCHAR(200) NOT NULL,
    description     TEXT,
    status          VARCHAR(20) NOT NULL DEFAULT 'pending',
    priority        SMALLINT NOT NULL DEFAULT 1,
    target_servers  UUID[] NOT NULL,
    runbook_id      UUID,
    agent_session_id UUID,
    created_by      UUID NOT NULL,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    completed_at    TIMESTAMPTZ,
    result_summary  TEXT
);

-- Approval Requests
CREATE TABLE approval_requests (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    task_id         UUID NOT NULL REFERENCES ops_tasks(id),
    command         TEXT NOT NULL,
    risk_level      SMALLINT NOT NULL,
    status          VARCHAR(20) NOT NULL DEFAULT 'pending',
    decided_by      UUID,
    decided_at      TIMESTAMPTZ,
    reason          TEXT,
    expires_at      TIMESTAMPTZ NOT NULL,
    notification_channels VARCHAR(20)[]
);

-- Runbooks
CREATE TABLE runbooks (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(200) NOT NULL,
    description     TEXT,
    trigger_type    VARCHAR(30),
    prompt_template TEXT NOT NULL,
    allowed_tools   VARCHAR(50)[] NOT NULL,
    max_risk_level  SMALLINT NOT NULL DEFAULT 1,
    auto_approve    BOOLEAN NOT NULL DEFAULT FALSE,
    is_active       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Standing Orders
CREATE TABLE standing_orders (
    id              VARCHAR(30) PRIMARY KEY,
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(200) NOT NULL,
    description     TEXT,
    defined_in_session_id UUID NOT NULL,
    last_modified_in_session_id UUID,
    trigger_type    VARCHAR(20) NOT NULL,
    trigger_config  JSONB NOT NULL,
    targets         JSONB NOT NULL,
    agent_prompt    TEXT NOT NULL,
    agent_skills    VARCHAR(100)[],
    runbook_id      UUID REFERENCES runbooks(id),
    max_risk_level  SMALLINT NOT NULL DEFAULT 0,
    max_turns       INTEGER NOT NULL DEFAULT 20,
    max_budget_usd  NUMERIC(6,2),
    decision_boundary JSONB NOT NULL,
    escalation_policy_id UUID,
    status          VARCHAR(20) NOT NULL DEFAULT 'active',
    valid_from      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    valid_until     TIMESTAMPTZ,
    created_by      UUID NOT NULL,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_standing_orders_status ON standing_orders(status) WHERE status = 'active';
CREATE INDEX idx_standing_orders_trigger ON standing_orders(trigger_type);

-- Standing Order Executions
CREATE TABLE standing_order_executions (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    order_id        VARCHAR(30) NOT NULL REFERENCES standing_orders(id),
    trigger_type    VARCHAR(20) NOT NULL,
    trigger_context JSONB,
    session_id      VARCHAR(100),
    status          VARCHAR(20) NOT NULL DEFAULT 'running',
    result_summary  TEXT,
    actions_taken   JSONB DEFAULT '[]',
    error           TEXT,
    escalated_at    TIMESTAMPTZ,
    escalation_channel VARCHAR(20),
    human_response  JSONB,
    responded_by    UUID,
    responded_at    TIMESTAMPTZ,
    started_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    completed_at    TIMESTAMPTZ,
    duration_ms     INTEGER
);

CREATE INDEX idx_so_executions_order ON standing_order_executions(order_id, started_at DESC);
CREATE INDEX idx_so_executions_status ON standing_order_executions(status) WHERE status IN ('running', 'awaiting_human');

-- Servers
CREATE TABLE servers (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(100) NOT NULL UNIQUE,
    host            VARCHAR(255) NOT NULL,
    port            INTEGER NOT NULL DEFAULT 22,
    environment     VARCHAR(20) NOT NULL,
    role            VARCHAR(30) NOT NULL,
    cluster_id      UUID,
    ssh_user        VARCHAR(50) NOT NULL,
    credential_id   UUID NOT NULL,
    network_type    VARCHAR(20) NOT NULL DEFAULT 'public',
    jump_server_id  UUID REFERENCES servers(id),
    ssh_options     JSONB DEFAULT '{}',
    tags            JSONB DEFAULT '{}',
    status          VARCHAR(20) NOT NULL DEFAULT 'active',
    description     TEXT,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_servers_environment ON servers(environment);

-- Clusters
CREATE TABLE clusters (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(100) NOT NULL UNIQUE,
    type            VARCHAR(20) NOT NULL,
    environment     VARCHAR(20) NOT NULL,
    description     TEXT,
    kubeconfig      TEXT,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Credentials
CREATE TABLE credentials (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(100) NOT NULL,
    type            VARCHAR(20) NOT NULL,
    encrypted_value BYTEA NOT NULL,
    iv              BYTEA NOT NULL,
    fingerprint     VARCHAR(100),
    key_type        VARCHAR(20),
    created_by      UUID,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    expires_at      TIMESTAMPTZ,
    last_used_at    TIMESTAMPTZ
);

-- Alert Rules
CREATE TABLE alert_rules (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(200) NOT NULL,
    metric_type     VARCHAR(30) NOT NULL,
    condition       JSONB NOT NULL,
    severity        VARCHAR(20) NOT NULL,
    target_servers  UUID[],
    runbook_id      UUID,
    is_active       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Alert Events
CREATE TABLE alert_events (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    rule_id         UUID NOT NULL REFERENCES alert_rules(id),
    server_id       UUID NOT NULL,
    severity        VARCHAR(20) NOT NULL,
    message         TEXT NOT NULL,
    metric_value    DOUBLE PRECISION,
    status          VARCHAR(20) NOT NULL DEFAULT 'firing',
    fired_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    resolved_at     TIMESTAMPTZ,
    acknowledged_by UUID
);

-- Contacts
CREATE TABLE contacts (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    user_id         UUID NOT NULL,
    name            VARCHAR(100) NOT NULL,
    phone           VARCHAR(20),
    email           VARCHAR(200),
    telegram_id     VARCHAR(100),
    wechat_id       VARCHAR(100),
    preferred_channel VARCHAR(20) NOT NULL DEFAULT 'websocket',
    role            VARCHAR(50),
    is_active       BOOLEAN NOT NULL DEFAULT TRUE
);

-- Messages
CREATE TABLE messages (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    contact_id      UUID NOT NULL REFERENCES contacts(id),
    channel_type    VARCHAR(20) NOT NULL,
    direction       VARCHAR(10) NOT NULL,
    content         TEXT NOT NULL,
    priority        VARCHAR(10) NOT NULL DEFAULT 'normal',
    delivery_status VARCHAR(20) NOT NULL DEFAULT 'pending',
    related_task_id UUID,
    sent_at         TIMESTAMPTZ,
    delivered_at    TIMESTAMPTZ,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Escalation Policies
CREATE TABLE escalation_policies (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(100) NOT NULL,
    severity        VARCHAR(20) NOT NULL,
    steps           JSONB NOT NULL,
    is_default      BOOLEAN NOT NULL DEFAULT FALSE
);

-- Audit Logs (append-only)
CREATE TABLE audit_logs (
    id              BIGSERIAL PRIMARY KEY,
    tenant_id       VARCHAR(20) NOT NULL,
    action_type     VARCHAR(50) NOT NULL,
    actor_type      VARCHAR(20) NOT NULL,
    actor_id        VARCHAR(100),
    resource_type   VARCHAR(50),
    resource_id     VARCHAR(100),
    detail          JSONB NOT NULL,
    ip_address      INET,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_audit_logs_action ON audit_logs(action_type, created_at);
CREATE INDEX idx_audit_logs_actor ON audit_logs(actor_id, created_at);
CREATE INDEX idx_audit_logs_resource ON audit_logs(resource_type, resource_id);

-- =========================================================================
-- Auth Tables
-- =========================================================================

-- Users
CREATE TABLE users (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    email           VARCHAR(255) NULL,
    phone           VARCHAR(30) NULL,
    password_hash   VARCHAR(255) NOT NULL,
    name            VARCHAR(100) NOT NULL,
    roles           VARCHAR(30)[] NOT NULL DEFAULT '{viewer}',
    is_active       BOOLEAN NOT NULL DEFAULT TRUE,
    last_login_at   TIMESTAMPTZ,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT users_email_unique UNIQUE (email),
    CONSTRAINT users_phone_unique UNIQUE (phone)
);

CREATE INDEX idx_users_active ON users(is_active) WHERE is_active = TRUE;

-- Roles
CREATE TABLE roles (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(50) NOT NULL UNIQUE,
    permissions     VARCHAR(100)[] NOT NULL DEFAULT '{}',
    description     TEXT,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- API Keys
CREATE TABLE api_keys (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    user_id         UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    key_hash        VARCHAR(255) NOT NULL,
    name            VARCHAR(100) NOT NULL,
    permissions     VARCHAR(100)[] NOT NULL DEFAULT '{}',
    expires_at      TIMESTAMPTZ,
    last_used_at    TIMESTAMPTZ,
    is_active       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_api_keys_user ON api_keys(user_id);
CREATE INDEX idx_api_keys_hash ON api_keys(key_hash);

-- =========================================================================
-- Agent Service - Additional Tables
-- =========================================================================

-- Conversation Messages (multi-turn dialogue history per session)
CREATE TABLE conversation_messages (
    id                UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id         VARCHAR(20) NOT NULL,
    session_id        UUID NOT NULL REFERENCES agent_sessions(id) ON DELETE CASCADE,
    role              VARCHAR(20) NOT NULL,
    content           TEXT NOT NULL,
    tool_calls        JSONB,
    tool_results      JSONB,
    attachments       JSONB,
    token_count       INTEGER,
    sequence_number   INTEGER NOT NULL,
    created_at        TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_conversation_messages_session
    ON conversation_messages(session_id, sequence_number ASC);
CREATE INDEX idx_conversation_messages_session_recent
    ON conversation_messages(session_id, sequence_number DESC);

-- Agent Tasks
CREATE TABLE agent_tasks (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    session_id      UUID NOT NULL REFERENCES agent_sessions(id) ON DELETE CASCADE,
    prompt          TEXT NOT NULL,
    status          VARCHAR(20) NOT NULL DEFAULT 'pending',
    result          TEXT,
    tokens_used     INTEGER,
    started_at      TIMESTAMPTZ,
    completed_at    TIMESTAMPTZ,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_agent_tasks_session ON agent_tasks(session_id);
CREATE INDEX idx_agent_tasks_status ON agent_tasks(status) WHERE status IN ('pending', 'running');

-- Skills
CREATE TABLE skills (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(100) NOT NULL UNIQUE,
    category        VARCHAR(50) NOT NULL DEFAULT 'general',
    description     TEXT,
    content         TEXT NOT NULL,
    tags            VARCHAR(50)[] DEFAULT '{}',
    is_active       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_skills_category ON skills(category);

-- Hook Scripts
CREATE TABLE hook_scripts (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    name            VARCHAR(100) NOT NULL UNIQUE,
    event           VARCHAR(30) NOT NULL,
    tool_pattern    VARCHAR(200) NOT NULL DEFAULT '*',
    script          TEXT NOT NULL,
    timeout         INTEGER NOT NULL DEFAULT 30,
    enabled         BOOLEAN NOT NULL DEFAULT TRUE,
    description     TEXT,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_hook_scripts_event ON hook_scripts(event);

-- =========================================================================
-- Monitor Service - Additional Tables
-- =========================================================================

-- Health Check Results
CREATE TABLE health_check_results (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    server_id       UUID NOT NULL,
    server_host     VARCHAR(255),
    check_type      VARCHAR(20) NOT NULL,
    status          VARCHAR(20) NOT NULL,
    latency_ms      INTEGER,
    checked_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    error           TEXT,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_health_checks_server ON health_check_results(server_id, checked_at DESC);
CREATE INDEX idx_health_checks_status ON health_check_results(status) WHERE status != 'healthy';

-- Metric Snapshots
CREATE TABLE metric_snapshots (
    id              BIGSERIAL PRIMARY KEY,
    tenant_id       VARCHAR(20) NOT NULL,
    server_id       UUID NOT NULL,
    metric_type     VARCHAR(50) NOT NULL,
    value           DOUBLE PRECISION NOT NULL,
    recorded_at     TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_metrics_server_type ON metric_snapshots(server_id, metric_type, recorded_at DESC);
CREATE INDEX idx_metrics_recorded ON metric_snapshots(recorded_at);

-- Usage Records (for billing metering)
CREATE TABLE usage_records (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id       VARCHAR(20) NOT NULL,
    task_id         UUID NOT NULL,
    session_id      UUID NOT NULL,
    engine_type     VARCHAR(30) NOT NULL,
    input_tokens    INTEGER NOT NULL DEFAULT 0,
    output_tokens   INTEGER NOT NULL DEFAULT 0,
    total_tokens    INTEGER NOT NULL DEFAULT 0,
    cost_usd        NUMERIC(10, 6) NOT NULL DEFAULT 0,
    model           VARCHAR(100) NOT NULL DEFAULT '',
    recorded_at     TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_usage_records_tenant_month ON usage_records(tenant_id, recorded_at DESC);
CREATE INDEX idx_usage_records_task ON usage_records(task_id);
