import { Callout } from "../components/Callout";
import { CodeBlock } from "../components/CodeBlock";

export function RbacGuide() {
  return (
    <div>
      <h1 id="rbac">RBAC & Permissions</h1>
      <p>
        Veylant IA enforces Role-Based Access Control on every request. Roles are stored in the{" "}
        <code>users</code> table and embedded in the HS256 JWT at login time. A role cannot be
        elevated at runtime — a new token must be issued after a role change.
      </p>

      <h2 id="roles">Roles</h2>
      <div className="space-y-4 my-4">
        {[
          {
            role: "admin",
            color: "bg-red-100 dark:bg-red-900/40 text-red-700 dark:text-red-300",
            description: "Full access. Can manage routing policies, users, providers, feature flags, and read all compliance/audit data. Has unrestricted model access.",
          },
          {
            role: "manager",
            color: "bg-amber-100 dark:bg-amber-900/40 text-amber-700 dark:text-amber-300",
            description: "Read-write access to routing policies and user profiles. Can run AI inference with any model. Cannot manage feature flags or access compliance reports.",
          },
          {
            role: "user",
            color: "bg-blue-100 dark:bg-blue-900/40 text-blue-700 dark:text-blue-300",
            description: "Inference only. Restricted to the model list in rbac.user_allowed_models (default: gpt-4o-mini, mistral-medium). No admin API access.",
          },
          {
            role: "auditor",
            color: "bg-purple-100 dark:bg-purple-900/40 text-purple-700 dark:text-purple-300",
            description: "Read-only access to audit logs, costs, and compliance data. Cannot call /v1/chat/completions. Intended for compliance officers and DPOs.",
          },
        ].map((item) => (
          <div key={item.role} className="rounded-lg border bg-card p-4 flex items-start gap-3">
            <span className={`text-xs font-bold px-2 py-0.5 rounded font-mono shrink-0 ${item.color}`}>
              {item.role}
            </span>
            <p className="text-sm text-muted-foreground leading-relaxed">{item.description}</p>
          </div>
        ))}
      </div>

      <h2 id="permission-matrix">Permission Matrix</h2>
      <div className="overflow-x-auto my-4">
        <table className="w-full text-sm border rounded-lg overflow-hidden">
          <thead>
            <tr className="bg-muted/50 border-b">
              <th className="text-left px-4 py-2.5 font-semibold">Endpoint</th>
              <th className="text-center px-3 py-2.5 font-semibold">admin</th>
              <th className="text-center px-3 py-2.5 font-semibold">manager</th>
              <th className="text-center px-3 py-2.5 font-semibold">user</th>
              <th className="text-center px-3 py-2.5 font-semibold">auditor</th>
            </tr>
          </thead>
          <tbody>
            {[
              { ep: "POST /v1/auth/login", admin: "✓", manager: "✓", user: "✓", auditor: "✓" },
              { ep: "POST /v1/chat/completions", admin: "✓", manager: "✓", user: "✓ (limited models)", auditor: "✗" },
              { ep: "POST /v1/pii/analyze", admin: "✓", manager: "✓", user: "✓", auditor: "✓" },
              { ep: "GET /v1/admin/policies", admin: "✓", manager: "✓", user: "✗", auditor: "✗" },
              { ep: "POST/PUT/DELETE /v1/admin/policies", admin: "✓", manager: "✓", user: "✗", auditor: "✗" },
              { ep: "GET/POST/PUT/DELETE /v1/admin/users", admin: "✓", manager: "read only", user: "✗", auditor: "✗" },
              { ep: "GET /v1/admin/logs", admin: "✓", manager: "✓", user: "✗", auditor: "✓" },
              { ep: "GET /v1/admin/costs", admin: "✓", manager: "✓", user: "✗", auditor: "✓" },
              { ep: "GET /v1/admin/compliance/*", admin: "✓", manager: "✗", user: "✗", auditor: "✓" },
              { ep: "POST/PUT/DELETE /v1/admin/compliance/*", admin: "✓", manager: "✗", user: "✗", auditor: "✗" },
              { ep: "GET/PUT/DELETE /v1/admin/flags", admin: "✓", manager: "✗", user: "✗", auditor: "✗" },
              { ep: "GET /v1/admin/providers/status", admin: "✓", manager: "✓", user: "✗", auditor: "✗" },
              { ep: "GET/POST/PUT/DELETE /v1/admin/providers", admin: "✓", manager: "✗", user: "✗", auditor: "✗" },
              { ep: "GET/PUT/DELETE /v1/admin/rate-limits", admin: "✓", manager: "✗", user: "✗", auditor: "✗" },
            ].map((row) => (
              <tr key={row.ep} className="border-b last:border-0">
                <td className="px-4 py-2.5 font-mono text-xs">{row.ep}</td>
                {[row.admin, row.manager, row.user, row.auditor].map((v, i) => (
                  <td key={i} className={`px-3 py-2.5 text-xs text-center ${v === "✗" ? "text-muted-foreground" : v === "✓" ? "text-green-600 dark:text-green-400 font-medium" : "text-amber-600 dark:text-amber-400"}`}>
                    {v}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <h2 id="model-restrictions">Model Restrictions</h2>
      <p>
        Users with the <code>user</code> role can only access models listed in{" "}
        <code>rbac.user_allowed_models</code>. Requests to other models are rejected with 403:
      </p>
      <CodeBlock
        language="yaml"
        code={`# config.yaml
rbac:
  user_allowed_models:
    - "gpt-4o-mini"
    - "mistral-medium-latest"
    - "claude-3-haiku-20240307"`}
      />
      <CodeBlock
        language="json"
        code={`// 403 response when a 'user' requests gpt-4o:
{
  "error": {
    "type": "permission_error",
    "message": "role 'user' does not have access to model 'gpt-4o'. Allowed: gpt-4o-mini, mistral-medium-latest, claude-3-haiku-20240307",
    "code": "permission_denied"
  }
}`}
      />

      <Callout type="tip" title="admin and manager bypass model restrictions">
        The <code>admin</code> and <code>manager</code> roles have unrestricted model access —{" "}
        <code>user_allowed_models</code> does not apply to them.
      </Callout>

      <h2 id="managing-roles">Managing User Roles via the Admin API</h2>
      <p>
        Roles are managed through the <code>/v1/admin/users</code> endpoints. After updating a
        user's role, they must log in again to receive a new token with the updated claims.
      </p>

      <CodeBlock
        language="bash"
        code={`# List all users
curl "http://localhost:8090/v1/admin/users" \\
  -H "Authorization: Bearer $ADMIN_TOKEN"

# Create a new user with a specific role
curl -X POST "http://localhost:8090/v1/admin/users" \\
  -H "Authorization: Bearer $ADMIN_TOKEN" \\
  -H "Content-Type: application/json" \\
  -d '{
    "email": "alice@acme.com",
    "password": "SecurePass123!",
    "name": "Alice Martin",
    "role": "auditor",
    "department": "Legal"
  }'

# Promote a user to manager
curl -X PUT "http://localhost:8090/v1/admin/users/user-uuid" \\
  -H "Authorization: Bearer $ADMIN_TOKEN" \\
  -H "Content-Type: application/json" \\
  -d '{
    "role": "manager",
    "department": "Finance"
  }'

# Deactivate a user (GDPR soft-delete)
curl -X DELETE "http://localhost:8090/v1/admin/users/user-uuid" \\
  -H "Authorization: Bearer $ADMIN_TOKEN"`}
      />

      <Callout type="warning" title="Role changes require a new token">
        JWT tokens embed the role at login time. After changing a user's role via the API, the user
        must log out and log in again. The old token remains valid until its <code>exp</code> claim
        (controlled by <code>auth.jwt_ttl_hours</code>).
      </Callout>

      <h2 id="bulk-import">Bulk User Import</h2>
      <p>
        For tenant onboarding, use the provided script to bulk-import users from a CSV file:
      </p>
      <CodeBlock
        language="bash"
        code={`# CSV format: email,first_name,last_name,department,role
cat > users.csv << 'EOF'
alice@acme.com,Alice,Martin,Legal,user
bob@acme.com,Bob,Dupont,Finance,manager
carol@acme.com,Carol,Lefebvre,IT,auditor
EOF

# Import (requires make dev to be running)
./deploy/onboarding/import-users.sh users.csv`}
      />
    </div>
  );
}
