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

export function AuthenticationPage() {
  return (
    <div>
      <h1 id="authentication">Authentication</h1>
      <p>
        Veylant IA uses a local email/password authentication system. Users log in with their
        credentials to receive a signed JWT (HS256). This token must be sent as a Bearer token on
        all protected <code>/v1/*</code> requests.
      </p>

      <h2 id="login">Login — Obtain a Token</h2>
      <ApiEndpoint
        method="POST"
        path="/v1/auth/login"
        description="Authenticate with email and password. Returns a signed JWT and the user profile."
      />

      <ParamTable
        title="Request Body"
        params={[
          { name: "email", type: "string", required: true, description: "User email address." },
          { name: "password", type: "string", required: true, description: "User password (bcrypt-hashed at rest)." },
        ]}
      />

      <CodeBlock
        language="bash"
        code={`curl -X POST http://localhost:8090/v1/auth/login \\
  -H "Content-Type: application/json" \\
  -d '{
    "email": "admin@veylant.dev",
    "password": "admin123"
  }'`}
      />

      <CodeBlock
        language="json"
        code={`// 200 — Login successful
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "a1b2c3d4-0000-0000-0000-000000000001",
    "email": "admin@veylant.dev",
    "name": "Admin",
    "role": "admin",
    "tenant_id": "dev-tenant",
    "department": "IT"
  }
}

// 401 — Invalid credentials
{
  "error": {
    "type": "authentication_error",
    "message": "invalid email or password",
    "code": "invalid_api_key"
  }
}`}
      />

      <Callout type="info" title="Token lifetime">
        Tokens are valid for the duration configured in <code>auth.jwt_ttl_hours</code> (default:{" "}
        <code>24</code> hours). The frontend automatically logs the user out when the token expires.
      </Callout>

      <h2 id="bearer-token">Using the Token</h2>
      <p>
        Pass the token in the <code>Authorization</code> header on every protected request:
      </p>
      <CodeBlock
        language="bash"
        code={`# Store the token after login
TOKEN=$(curl -s -X POST http://localhost:8090/v1/auth/login \\
  -H "Content-Type: application/json" \\
  -d '{"email":"admin@veylant.dev","password":"admin123"}' | jq -r '.token')

# Use it on subsequent requests
curl http://localhost:8090/v1/chat/completions \\
  -H "Authorization: Bearer $TOKEN" \\
  -H "Content-Type: application/json" \\
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Bonjour"}]}'`}
      />

      <CodeBlock
        language="python"
        code={`import httpx

# Step 1 — login
resp = httpx.post("http://localhost:8090/v1/auth/login", json={
    "email": "admin@veylant.dev",
    "password": "admin123",
})
token = resp.json()["token"]

# Step 2 — use the OpenAI-compatible endpoint
client = httpx.Client(
    base_url="http://localhost:8090/v1",
    headers={"Authorization": f"Bearer {token}"},
)
chat = client.post("/chat/completions", json={
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "Résume ce contrat"}],
})
print(chat.json()["choices"][0]["message"]["content"])`}
      />

      <h2 id="jwt-claims">JWT Claims</h2>
      <p>
        Tokens are HS256-signed. The proxy extracts the following claims on each request:
      </p>
      <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">Claim</th>
              <th className="text-left px-4 py-2.5 font-semibold">Type</th>
              <th className="text-left px-4 py-2.5 font-semibold">Description</th>
            </tr>
          </thead>
          <tbody>
            {[
              { claim: "sub", type: "string (UUID)", desc: "User ID — used in audit logs and GDPR access requests." },
              { claim: "email", type: "string", desc: "User email address." },
              { claim: "name", type: "string", desc: "Display name shown in the dashboard." },
              { claim: "role", type: "string", desc: "RBAC role: admin | manager | user | auditor." },
              { claim: "tenant_id", type: "string", desc: "Tenant UUID — enforces data isolation via PostgreSQL RLS." },
              { claim: "department", type: "string", desc: "Department name — used in routing rule conditions." },
              { claim: "exp", type: "unix timestamp", desc: "Token expiry (derived from auth.jwt_ttl_hours)." },
            ].map((row) => (
              <tr key={row.claim} className="border-b last:border-0">
                <td className="px-4 py-2.5 font-mono text-xs">{row.claim}</td>
                <td className="px-4 py-2.5 text-muted-foreground text-xs">{row.type}</td>
                <td className="px-4 py-2.5 text-muted-foreground text-xs">{row.desc}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <h2 id="test-users">Pre-configured Dev Users</h2>
      <p>
        The dev stack seeds two users in the <code>users</code> table (migration 000010):
      </p>
      <CodeBlock
        language="bash"
        code={`# Admin — full access, unrestricted model access
email:    admin@veylant.dev
password: admin123
role:     admin

# Regular user — inference only, restricted to allowed models
# (create this user via POST /v1/admin/users if needed)
email:    user@veylant.dev
password: user123
role:     user`}
      />

      <h2 id="config">Auth Configuration</h2>
      <CodeBlock
        language="yaml"
        code={`# config.yaml
auth:
  jwt_secret: "change-me-in-production-min-32-chars"
  jwt_ttl_hours: 24`}
      />
      <Callout type="warning" title="Secret rotation">
        Set <code>VEYLANT_AUTH_JWT_SECRET</code> in production to a random 32-byte value. Rotating
        the secret immediately invalidates all active sessions.
      </Callout>

      <h2 id="error-responses">Auth Error Responses</h2>
      <p>Authentication errors always return OpenAI-format JSON:</p>
      <CodeBlock
        language="json"
        code={`// 401 — Missing or invalid token
{
  "error": {
    "type": "authentication_error",
    "message": "invalid or missing authorization token",
    "code": "invalid_api_key"
  }
}

// 403 — Valid token, insufficient role for the model
{
  "error": {
    "type": "permission_error",
    "message": "role 'user' does not have access to model 'gpt-4o'. Allowed: gpt-4o-mini",
    "code": "permission_denied"
  }
}

// 429 — Rate limit exceeded
{
  "error": {
    "type": "rate_limit_error",
    "message": "rate limit exceeded",
    "code": "rate_limit_exceeded"
  }
}`}
      />
    </div>
  );
}
