import React, { useEffect, useRef } from 'react';

// Minimal Markdown to HTML renderer (headings, bold, inline-code, tables, hr, ul, ol, paragraphs)
function mdToHtml(md) {
  const lines = md.split('\n');
  const out   = [];
  let i = 0, inUl = false, inOl = false, inTable = false;

  const close = () => {
    if (inUl)    { out.push('</ul>');              inUl    = false; }
    if (inOl)    { out.push('</ol>');              inOl    = false; }
    if (inTable) { out.push('</tbody></table>');   inTable = false; }
  };
  const inline = s =>
    s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
     .replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>')
     .replace(/`([^`]+)`/g,'<code>$1</code>');

  while (i < lines.length) {
    const line = lines[i];
    if (line.startsWith('```')) { close(); i++; while (i < lines.length && !lines[i].startsWith('```')) i++; i++; continue; }
    if (/^---+$/.test(line.trim())) { close(); out.push('<hr>'); i++; continue; }
    const hm = line.match(/^(#{1,4})\s+(.+)/);
    if (hm) { close(); const lv=hm[1].length, id=hm[2].toLowerCase().replace(/[^a-z0-9]+/g,'-'); out.push(`<h${lv} id="${id}">${inline(hm[2])}</h${lv}>`); i++; continue; }
    if (line.trim().startsWith('|')) {
      const cells = line.trim().replace(/^\|||\|$/g,'').split('|').map(c=>c.trim());
      if (!inTable) { close(); inTable=true; out.push('<table><thead><tr>'); cells.forEach(c=>out.push(`<th>${inline(c)}</th>`)); out.push('</tr></thead><tbody>'); i++; if (i < lines.length && /^[\|\s\:\-]+$/.test(lines[i])) i++; continue; }
      else { out.push('<tr>'); cells.forEach(c=>out.push(`<td>${inline(c)}</td>`)); out.push('</tr>'); i++; continue; }
    }
    const ul = line.match(/^[-*]\s+(.*)/);
    if (ul) { if (inTable) close(); if (!inUl) { if (inOl){out.push('</ol>');inOl=false;} out.push('<ul>');inUl=true; } out.push(`<li>${inline(ul[1])}</li>`); i++; continue; }
    const ol = line.match(/^\d+\.\s+(.*)/);
    if (ol) { if (inTable) close(); if (!inOl) { if (inUl){out.push('</ul>');inUl=false;} out.push('<ol>');inOl=true; } out.push(`<li>${inline(ol[1])}</li>`); i++; continue; }
    if (line.trim() === '') { close(); i++; continue; }
    close(); out.push(`<p>${inline(line)}</p>`); i++;
  }
  close();
  return out.join('\n');
}

function buildToc(md) {
  return md.split('\n').reduce((acc, line) => {
    const m = line.match(/^(#{1,2})\s+(.+)/);
    if (m) acc.push({ level: m[1].length, text: m[2], id: m[2].toLowerCase().replace(/[^a-z0-9]+/g,'-') });
    return acc;
  }, []);
}

// ——— Styles ——————————————————————————————————————————————————————————————————
const S = {
  overlay: { position:'fixed', inset:0, background:'rgba(0,0,0,0.75)', zIndex:2000, display:'flex', alignItems:'flex-start', justifyContent:'flex-end' },
  panel:   { background:'#111217', color:'#f8f9fa', width:'760px', maxWidth:'95vw', height:'100vh', overflowY:'auto', boxShadow:'-4px 0 32px rgba(0,0,0,0.85)', display:'flex', flexDirection:'column' },
  header:  { background:'linear-gradient(135deg,#000000,#151622)', color:'white', padding:'22px 28px', position:'sticky', top:0, zIndex:10, borderBottom:'1px solid #222', display:'flex', alignItems:'center', justifyContent:'space-between' },
  closeBtn:{ background:'none', border:'none', color:'white', fontSize:'22px', cursor:'pointer', lineHeight:1 },
  toc:     { background:'#0d1117', borderBottom:'1px solid #1e1f2e', padding:'10px 32px', display:'flex', flexWrap:'wrap', gap:'4px 18px', fontSize:'11px' },
  body:    { padding:'28px 32px', flex:1, fontSize:'13px', lineHeight:'1.75' },
  footer:  { padding:'14px 32px', borderTop:'1px solid #1e1f2e', fontSize:'11px', color:'#555770', textAlign:'center' },
};

const CSS = `
.adm h1 { font-size:21px; font-weight:800; color:#f8f9fa; margin:28px 0 10px; border-bottom:1px solid #2a2b3a; padding-bottom:8px }
.adm h2 { font-size:16px; font-weight:700; color:#d4af37; margin:28px 0 6px; letter-spacing:.2px }
.adm h3 { font-size:12px; font-weight:700; color:#90caf9; margin:18px 0 4px; text-transform:uppercase; letter-spacing:.5px }
.adm h4 { font-size:13px; font-weight:600; color:#b0b8d0; margin:14px 0 4px }
.adm p  { color:#c8ccd8; margin:5px 0 10px }
.adm hr { border:none; border-top:1px solid #2a2b3a; margin:22px 0 }
.adm strong { color:#f8f9fa }
.adm code { background:#0d1117; color:#79c0ff; border:1px solid #2a2b3a; border-radius:4px; padding:1px 6px; font-family:'Consolas','Fira Code',monospace; font-size:12px }
.adm ul { padding-left:20px; margin:5px 0 10px; color:#c8ccd8 }
.adm ol { padding-left:20px; margin:5px 0 10px; color:#c8ccd8 }
.adm li { margin:4px 0 }
.adm table { width:100%; border-collapse:collapse; font-size:12px; background:#181924; border-radius:6px; overflow:hidden; border:1px solid #2a2b3a; margin:10px 0 16px }
.adm th { background:#050608; padding:8px 12px; text-align:left; color:#f8f9fa; font-weight:600; font-size:11px; text-transform:uppercase; border-bottom:1px solid #2a2b3a }
.adm td { padding:8px 12px; border-bottom:1px solid #202231; color:#c8ccd8 }
.adm tr:last-child td { border-bottom:none }
.adm tr:hover td { background:#1e1f2e }
`;

// ——— Admin guide content (no install / Docker content) ————————————————————
const GUIDE_MD = `# CPAS Tracker — Admin Guide

Internal tool for CPAS violation documentation, workforce standing management, and audit compliance. All data is stored locally in the Docker container volume — there is no external dependency.

---

## How Scoring Works

Every violation carries a **point value** set at the time of submission. Points count toward an employee's score only within a **rolling 90-day window** — once a violation is older than 90 days it automatically drops off and the score recalculates.

Negated (voided) violations are excluded from scoring immediately. Hard-deleted violations are removed from the record entirely.

## Tier Reference

| Points | Tier | Label |
|--------|------|-------|
| 0–4 | 0–1 | Elite Standing |
| 5–9 | 1 | Realignment |
| 10–14 | 2 | Administrative Lockdown |
| 15–19 | 3 | Verification |
| 20–24 | 4 | Risk Mitigation |
| 25–29 | 5 | Final Decision |
| 30+ | 6 | Separation |

The **at-risk badge** on the dashboard flags anyone within 2 points of the next tier threshold so supervisors can act before escalation occurs.

---

## Feature Map

### Dashboard

The main view. Employees are sorted by active CPAS points, highest first.

- **Stat cards** — live counts: total employees, zero-point (elite), with active points, at-risk, highest score
- **Search / filter** — by name, department, or supervisor; narrows the table in real time
- **At-risk badge** — gold flag on rows where the employee is within 2 pts of the next tier
- **Audit Log button** — opens the filterable, paginated write-action log (top right of the dashboard toolbar)
- **Click any name** — opens that employee's full profile modal

---

### Logging a Violation

Use the **+ New Violation** tab.

1. Select an existing employee from the dropdown, or type a new name to create a record on-the-fly.
2. The **employee intelligence panel** loads their current tier badge and 90-day violation count before you commit.
3. Choose a violation type. The dropdown is grouped by category and shows prior 90-day counts inline for each type.
4. If the employee has a prior violation of the same type, the **recidivist auto-escalation** rule triggers — the points slider jumps to the maximum allowed for that violation type.
5. The **tier crossing warning** previews what tier the submission would land the employee in. Review before submitting.
6. Adjust points using the slider if discretionary reduction is warranted (within the violation's allowed min/max range).
7. **Employee Acknowledgment** (optional): if the employee is present and acknowledges receipt, enter their printed name and the acknowledgment date. This replaces the blank signature line on the PDF with a recorded acknowledgment and an "Acknowledged" badge. Leave blank if the employee is not present or declines.
8. Submit. A **PDF download link** appears immediately — download it for the employee's file.
9. **Toast notifications** confirm success or surface errors at the top right of the screen. Toasts auto-dismiss after a few seconds.

---

### Employee Profile Modal

Click any name on the dashboard to open their profile.

#### Overview section
Shows current tier badge, active points, and 90-day violation count.

#### Notes & Flags
Free-text field for HR context (e.g. "On PIP", "Union member", "Pending investigation", "FMLA"). Quick-add tag buttons pre-fill common statuses. Notes are visible to anyone who opens the profile but **do not affect CPAS scoring**. Edit inline; saves on blur.

#### Point Expiration Timeline
Visible when the employee has active points. Shows each active violation as a progress bar indicating how far through its 90-day window it is, days remaining until roll-off, and a **tier-drop indicator** for violations whose expiration would move the employee down a tier.

#### Violation History
Full record of all submissions — active, negated, and resolved.

- **Amend** — edit non-scoring fields (location, details, witness, submitted-by, incident time, acknowledged-by, acknowledged-date) on any active violation. Every change is logged as a field-level diff (old → new) with timestamp. Points, type, and incident date are immutable.
- **Negate** — soft-delete a violation with a resolution type and notes. The record is preserved in history; the points are immediately removed from the score. Fully reversible via **Restore**.
- **Hard delete** — permanent removal. Use only for genuine data entry errors.
- **PDF** — download the formal violation document for any historical record. If the violation has an employee acknowledgment on record, the PDF shows the filled-in name and date instead of blank signature lines.

All actions trigger **toast notifications** confirming success or surfacing errors.

#### Edit Employee
Update name, department, or supervisor. Changes are logged to the audit trail.

#### Merge Duplicate
If the same employee exists under two names, use Merge to reassign all violations from the duplicate to the canonical record. The duplicate is then deleted. This cannot be undone.

---

### Audit Log

Accessible from the dashboard toolbar (🔍 button). Append-only log of every write action in the system.

- Filter by entity type: **employee** or **violation**
- Filter by action: created, edited, merged, negated, restored, amended, deleted, notes updated
- Paginated with load-more; most recent entries first

The audit log is the authoritative record for compliance review. Nothing in it can be edited or deleted through the UI.

---

### Violation Amendment

Amendments allow corrections to a violation's non-scoring fields without deleting and re-submitting, which would disrupt the audit trail and the prior-points snapshot.

**Amendable fields:** incident time, location, details, submitted-by, witness name, acknowledged-by, acknowledged-date.

**Immutable fields:** violation type, incident date, point value.

Each amendment stores a before/after diff for every changed field. Amendment history is accessible from the violation card in the employee's history.

---

### Toast Notifications

All user actions across the application produce **toast notifications** — small slide-in messages at the top right of the screen.

- **Success** (green) — violation submitted, PDF downloaded, employee updated, etc.
- **Error** (red) — API failures, validation errors, PDF generation issues
- **Warning** (gold) — missing required fields, policy alerts
- **Info** (blue) — general informational messages

Toasts auto-dismiss after a few seconds (errors persist longer). Each toast has a progress bar countdown and a manual dismiss button. Up to 5 toasts can stack simultaneously.

---

## Immutability Rules — Quick Reference

| Action | Allowed? | Notes |
|--------|----------|-------|
| Edit violation type | No | Immutable after submission |
| Edit incident date | No | Immutable after submission |
| Edit point value | No | Immutable after submission |
| Edit location / details / witness | Yes | Via Amend |
| Edit acknowledged-by / acknowledged-date | Yes | Via Amend |
| Negate (void) a violation | Yes | Soft delete; reversible |
| Hard delete a violation | Yes | Permanent; use sparingly |
| Edit employee name / dept / supervisor | Yes | Logged to audit trail |
| Merge duplicate employees | Yes | Irreversible |
| Add / edit employee notes | Yes | Does not affect score |

---

## Roadmap

### Shipped

- Container scaffold, violation form, employee intelligence
- Recidivist auto-escalation, tier crossing warning
- PDF generation with prior-points snapshot
- Company dashboard, stat cards, at-risk badges
- Employee profile modal — full history, negate/restore, hard delete
- Employee edit and duplicate merge
- Violation amendment with field-level diff log
- Audit log — filterable, paginated, append-only
- Employee notes and flags with quick-add HR tags
- Point expiration timeline with tier-drop projections
- In-app admin guide (this panel)
- Acknowledgment signature field — employee name + date on form and PDF
- Toast notification system — global feedback for all user actions

---

### Near-term

These are well-scoped additions that fit the current architecture without major changes.

- **CSV export** — one endpoint returning violations or dashboard data as a downloadable CSV for payroll or external reporting.
- **Supervisor-scoped view** — filter the dashboard to a single supervisor's team via URL param; useful in multi-supervisor environments without requiring full auth.

---

### Planned

Larger features that require more design work or infrastructure.

- **Violation trends chart** — line/bar chart of violations over time, filterable by department or supervisor. Useful for identifying systemic patterns vs. isolated incidents. Recharts is already available in the frontend bundle.
- **Department heat map** — grid showing violation density and average CPAS score per department. Helps identify team-level risk early.
- **Draft / pending violations** — save a violation as a draft before it's officially logged. Useful when incidents need supervisor review or HR sign-off before they count toward the score.
- **At-risk threshold configuration** — make the 2-point at-risk warning threshold configurable per deployment rather than hardcoded.

---

### Future Considerations

These require meaningful infrastructure additions and should be evaluated against actual operational need before committing.

- **Multi-user auth** — role-based login (admin, supervisor, read-only). Currently the app assumes a trusted internal network with no authentication layer.
- **Tier escalation alerts** — email or in-app notification when an employee crosses into Tier 2+, automatically routed to their supervisor.
- **Scheduled digest** — weekly email summary to supervisors showing their employees' current standings and any approaching thresholds.
- **Automated DB backup** — scheduled snapshot of the database to a mounted backup volume or remote destination.
- **Bulk CSV import** — migrate historical violation records from paper logs or a prior system.
- **Dark/light theme toggle** — UI is currently dark-only.
`;

// ——— Component ——————————————————————————————————————————————————————————————
export default function ReadmeModal({ onClose }) {
  const bodyRef = useRef(null);
  const html    = mdToHtml(GUIDE_MD);
  const toc     = buildToc(GUIDE_MD);

  useEffect(() => {
    const h = e => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [onClose]);

  const scrollTo = id => {
    const el = bodyRef.current?.querySelector(`#${id}`);
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  return (
    <div style={S.overlay} onClick={e => { if (e.target === e.currentTarget) onClose(); }}>
      <style>{CSS}</style>

      <div style={S.panel} onClick={e => e.stopPropagation()}>

        {/* Header */}
        <div style={S.header}>
          <div>
            <div style={{ fontSize:'17px', fontWeight:800, letterSpacing:'.3px' }}>
              📋 CPAS Tracker — Admin Guide
            </div>
            <div style={{ fontSize:'11px', color:'#9ca0b8', marginTop:'3px' }}>
              Feature map · workflows · roadmap · Esc or click outside to close
            </div>
          </div>
          <button style={S.closeBtn} onClick={onClose} aria-label="Close">✕</button>
        </div>

        {/* TOC strip */}
        <div style={S.toc}>
          {toc.map(h => (
            <button key={h.id} onClick={() => scrollTo(h.id)} style={{
              background:'none', border:'none', cursor:'pointer', padding:'3px 0',
              color: h.level === 1 ? '#f8f9fa' : '#d4af37',
              fontWeight: h.level === 1 ? 700 : 500,
              fontSize:'11px',
            }}>
              {h.level === 2 ? '↳ ' : ''}{h.text}
            </button>
          ))}
        </div>

        {/* Body */}
        <div
          ref={bodyRef}
          style={S.body}
          className="adm"
          dangerouslySetInnerHTML={{ __html: html }}
        />

        {/* Footer */}
        <div style={S.footer}>
          CPAS Violation Tracker · internal admin use only
        </div>
      </div>
    </div>
  );
}
