import numpy as np
import pandas as pd
from ergodic import case_table, discover, estimate_effect, event_log, kpi_panel, process_map
from ergodic.process import END, START, filter_activities, performance, variant_table

# 1. Simulate 1,500 tickets over 90 days; timestamps are in hours.
#    Complex tickets get reviewed more often, and review adds 5 hours.
rng = np.random.default_rng(11)
n = 1500
complexity = rng.normal(size=n)
review = rng.uniform(size=n) < 1 / (1 + np.exp(-1.3 * complexity))
hours = np.maximum(20 + 6 * complexity + 5 * review + rng.normal(0, 2, n), 3)
opened = rng.uniform(0, 90 * 24, n)
rows = []
for i in range(n):
    steps = [("open", 0.0), ("triage", 1.0)] + [("review", 2.0)] * int(review[i])
    for activity, at in [*steps, ("close", hours[i])]:
        rows.append((f"T{i:04d}", activity, opened[i] + at, complexity[i]))
frame = pd.DataFrame(rows, columns=["ticket", "activity", "hour", "complexity"])
log = event_log(frame, case="ticket", activity="activity", timestamp="hour")
print(log)

# 2. Map the process: how often each step follows another, and the mean gap.
pmap = process_map(log)
for (a, b), arc in pmap.arcs.items():
    if a != START and b != END:
        print(f"{a:>6} -> {b:<6} {arc.count:5d} times  {arc.mean_gap:5.1f} h")

# 3. Summarize cycle times and variants, and filter to reviewed tickets.
perf = performance(log)
print(f"cycle time: median {perf.median_duration:.1f} h, p90 {perf.p90_duration:.1f} h")
for variant in variant_table(log):
    print(" > ".join(variant.sequence), f"{variant.share:.0%}", f"{variant.mean_duration:.1f} h")
print(filter_activities(log, mandatory=["review"]))

# 4. One row per ticket, then discover the graph and estimate the effect of review.
table = case_table(log, "review", "cycle_time")
print(table)
graph = discover(table.data, knowledge=table.knowledge, alpha=0.01).graph
print(sorted(edge.glyph() for edge in graph.edges))
estimate = estimate_effect(
    graph.as_kind("dag"), table.data, "review", "cycle_time", strategy="dml", random_state=0
)
print(estimate)

# 5. Weekly KPIs for the panel designs.
panel = kpi_panel(log, 7 * 24, kpis=("n_cases", "cycle_time"))
print(panel.to_pandas().head(3).round(1))
