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

export function PiiGuide() {
  return (
    <div>
      <h1 id="pii-detection">PII Detection & Anonymization</h1>
      <p>
        Veylant IA intercepts all AI prompts and runs a 3-layer PII detection pipeline before
        forwarding to the LLM. The entire pipeline must complete in <strong>under 50ms</strong>.
      </p>

      <h2 id="pipeline">Detection Pipeline</h2>
      <div className="my-4 rounded-lg border bg-zinc-950 text-zinc-100 p-4 font-mono text-xs leading-relaxed overflow-x-auto">
        <pre>{`Incoming prompt text
        │
        ▼
Layer 1: Regex (< 1ms)
  ─ IBAN: /[A-Z]{2}\\d{2}[A-Z0-9]{11,30}/
  ─ Email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/
  ─ Phone: /(?:\\+33|0)[1-9](?:[\\s.-]?\\d{2}){4}/
  ─ SSN: /\\d{1}\\s?\\d{2}\\s?\\d{2}\\s?\\d{2}\\s?\\d{3}\\s?\\d{3}\\s?\\d{2}/
  ─ Credit card: /\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}/
        │
        ▼
Layer 2: Presidio + spaCy NER (15–40ms)
  ─ PERSON: "John Smith", "Marie Dupont"
  ─ LOCATION: "Paris", "75001", "rue de Rivoli"
  ─ ORGANIZATION: "Acme Corp", "Banque de France"
  ─ DATE_TIME: "12/03/1985"
  ─ NRP: nationality, religion, political group
        │
        ▼
Layer 3: LLM validation (optional, V1.1)
  ─ For ambiguous cases scored 0.5–0.8
  ─ Sends short validation prompts to a fast LLM
  ─ Corrects false positives and false negatives
        │
        ▼
Anonymized prompt → forwarded to LLM provider`}</pre>
      </div>

      <h2 id="anonymization">Anonymization vs Pseudonymization</h2>
      <p>Veylant IA supports two modes:</p>

      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 my-4">
        <div className="rounded-lg border bg-card p-4">
          <h3 className="font-semibold text-sm mb-2">Anonymization (default)</h3>
          <p className="text-sm text-muted-foreground">
            PII is replaced with a type label. No mapping stored. Irreversible.
          </p>
          <CodeBlock
            language="text"
            code={`Input:  "Call John at +33 6 12 34 56 78"
Output: "Call [PERSON] at [PHONE_NUMBER]"`}
          />
        </div>
        <div className="rounded-lg border bg-card p-4">
          <h3 className="font-semibold text-sm mb-2">Pseudonymization</h3>
          <p className="text-sm text-muted-foreground">
            PII is replaced with a synthetic token. Mapping stored in Redis (encrypted, TTL-based).
            Reversible.
          </p>
          <CodeBlock
            language="text"
            code={`Input:   "Call John at +33 6 12 34 56 78"
Output:  "Call PERSON_001 at PHONE_001"
Mapping: PERSON_001 → "John" (Redis, AES-256-GCM, TTL=3600s)`}
          />
        </div>
      </div>

      <h2 id="redis-mapping">Redis Pseudonymization Mapping</h2>
      <p>
        When pseudonymization is enabled, the PII service stores mappings in Redis using the
        following key structure:
      </p>
      <CodeBlock
        language="text"
        code={`Key:   pii:{tenant_id}:{user_id}:{session_id}:{token}
Value: AES-256-GCM encrypted JSON {"original": "John Smith", "type": "PERSON"}
TTL:   3600 seconds (configurable)`}
      />

      <h2 id="latency">Latency Budget</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">Layer</th>
              <th className="text-left px-4 py-2.5 font-semibold">Typical latency</th>
              <th className="text-left px-4 py-2.5 font-semibold">P99 latency</th>
            </tr>
          </thead>
          <tbody>
            {[
              { layer: "Layer 1: Regex", typ: "< 1ms", p99: "< 2ms" },
              { layer: "Layer 2: NER (spaCy)", typ: "15–30ms", p99: "45ms" },
              { layer: "Redis write (pseudonymization)", typ: "< 2ms", p99: "5ms" },
              { layer: "Total pipeline (gRPC)", typ: "20–35ms", p99: "50ms" },
            ].map((row) => (
              <tr key={row.layer} className="border-b last:border-0">
                <td className="px-4 py-2.5 text-sm">{row.layer}</td>
                <td className="px-4 py-2.5 text-sm text-muted-foreground">{row.typ}</td>
                <td className="px-4 py-2.5 text-sm text-muted-foreground">{row.p99}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <Callout type="warning" title="Fail-open behavior">
        If the PII service is unreachable and <code>pii.fail_open=true</code> (default in
        development), requests are forwarded without anonymization and a warning is logged. In
        production, set <code>pii.fail_open=false</code> to return 503 instead.
      </Callout>

      <h2 id="disabling">Disabling PII per Request</h2>
      <p>
        There is no per-request PII bypass. PII is controlled globally via the{" "}
        <code>pii_detection</code> feature flag or the <code>pii.enabled</code> config key.
        Fine-grained per-rule PII control is planned for V1.1.
      </p>

      <h2 id="testing">Testing PII Detection</h2>
      <CodeBlock
        language="bash"
        code={`# Use the analyze endpoint directly
curl http://localhost:8090/v1/pii/analyze \\
  -H "Authorization: Bearer $TOKEN" \\
  -H "Content-Type: application/json" \\
  -d '{
    "text": "Contact Marie Dupont at marie.dupont@orange.fr or +33 1 23 45 67 89",
    "anonymize": true
  }'`}
      />

      <CodeBlock
        language="bash"
        code={`# Run Python unit tests for the PII service
pytest services/pii/tests/test_regex.py
pytest services/pii/tests/test_pipeline.py
pytest services/pii/tests/test_pseudo.py`}
      />
    </div>
  );
}
