import typer
from rich.console import Console
from rich.panel import Panel
from rich.table import Table

from pcapx.core.analyze import analyze_pcap
from pcapx.core.findings import generate_findings
from pcapx.core.exporters.md import export_md
from pcapx.core.exporters.json import export_iocs_json

app = typer.Typer()
console = Console()


@app.command()
def analyze(
    pcap: str,

    # Display flags
    p: bool = typer.Option(False, "-p", help="Show ports"),
    s: bool = typer.Option(False, "-s", help="Show services"),
    i: bool = typer.Option(False, "-i", help="Show IPs"),
    d: bool = typer.Option(False, "-d", help="Show DNS"),
    c: bool = typer.Option(False, "-c", help="Show connections"),
    t: bool = typer.Option(False, "-t", help="Show timeline"),
    f: bool = typer.Option(False, "-f", "--findings", help="Show findings only"),

    # Signal flags
    icmp_flag: bool = typer.Option(False, "--icmp", help="Show ICMP activity"),
    arp_flag: bool = typer.Option(False, "--arp", help="Show ARP activity"),

    # Meta
    a: bool = typer.Option(False, "-a", help="Show all"),
    e: bool = typer.Option(False, "-e", help="Export Markdown report"),
    j: bool = typer.Option(False, "-j", help="Export IOC JSON"),
):
    result = analyze_pcap(pcap)

    meta = result["meta"]
    index = result["index"]
    signals = result.get("signals", {})

    findings = generate_findings(result)

    # ================= FINDINGS-ONLY MODE =================
    if f:
        if not findings:
            console.print("[green]✔ No significant findings detected[/green]")
            return

        for fnd in findings:
            console.print(
                Panel(
                    f"[bold]{fnd['title']}[/bold]\n\n"
                    f"[bold]Severity:[/bold] {fnd['severity']}\n\n"
                    f"[bold]What happened:[/bold]\n{fnd['what_happened']}\n\n"
                    f"[bold]Why it matters:[/bold]\n{fnd['why_it_matters']}\n\n"
                    f"[bold]Affected assets:[/bold]\n"
                    + ", ".join(fnd.get("affected_assets", [])),
                    title=fnd["id"],
                    border_style="red"
                    if fnd["severity"] in ["HIGH", "CRITICAL"]
                    else "yellow",
                )
            )
        return

    no_flags = not any([p, s, i, d, c, t, icmp_flag, arp_flag, a])

    # ================= SUMMARY =================
    console.print(
        Panel.fit(
            f"[bold cyan]PCAPX[/bold cyan]\n\n"
            f"File: {meta['file']}\n"
            f"Packets: {meta['total_packets']}\n"
            f"Duration: {meta['duration']} sec\n"
            f"Risk Score: {meta['risk']}",
            title="Analysis Summary",
        )
    )

    # ================= PROTOCOLS =================
    proto = Table(title="Protocols")
    proto.add_column("Protocol")
    proto.add_column("Packets")

    for k, v in result["protocols"].items():
        proto.add_row(k, str(v))

    console.print(proto)

    # ================= PORTS =================
    if p or a or no_flags:
        ports = Table(title="Ports (Top 10)")
        ports.add_column("Port")
        ports.add_column("Packets")

        for k, v in index["ports"].most_common(10):
            ports.add_row(str(k), str(v))

        console.print(ports)

    # ================= SERVICES =================
    if s or a:
        svc = Table(title="Services")
        svc.add_column("Service")
        svc.add_column("Connections")

        for k, v in index["services"].items():
            svc.add_row(k, str(v))

        console.print(svc)

    # ================= IPS =================
    if i or a:
        ips = Table(title="IPs")
        ips.add_column("IP")

        for ip in index["ips"][:20]:
            ips.add_row(ip)

        console.print(ips)

    # ================= DNS =================
    if d or a:
        dns = Table(title="DNS Queries")
        dns.add_column("Domain")

        for q in index["dns"][:20]:
            dns.add_row(q)

        console.print(dns)

    # ================= CONNECTIONS =================
    if c or a:
        con = Table(title="Connections")
        con.add_column("Source")
        con.add_column("Destination")
        con.add_column("Service")

        for x in index["connections"][:25]:
            con.add_row(
                f"{x['src']}:{x['sport']}",
                f"{x['dst']}:{x['dport']}",
                x["service"],
            )

        console.print(con)

    # ================= TIMELINE =================
    if t or a:
        tl = Table(title="Timeline")
        tl.add_column("Time")
        tl.add_column("Event")
        tl.add_column("Detail")

        for e2 in result["timeline"][:30]:
            tl.add_row(str(e2["time"]), e2["type"], e2["detail"])

        console.print(tl)

    # ================= ICMP =================
    icmp = signals.get("icmp", {})
    if (icmp_flag or a) and icmp.get("summary", {}).get("total", 0):
        icmp_t = Table(title="ICMP Activity")
        icmp_t.add_column("Metric")
        icmp_t.add_column("Count")

        for k, v in icmp["summary"].items():
            icmp_t.add_row(k.replace("_", " ").title(), str(v))

        if icmp.get("flood_sources"):
            icmp_t.add_row("⚠ Flood Sources", ", ".join(icmp["flood_sources"]))

        console.print(icmp_t)

    # ================= ARP =================
    arp = signals.get("arp", {})
    if (arp_flag or a) and (arp.get("requests") or arp.get("replies")):
        arp_t = Table(title="ARP Activity")
        arp_t.add_column("Metric")
        arp_t.add_column("Count")

        arp_t.add_row("Who-has Requests", str(sum(arp["requests"].values())))
        arp_t.add_row("Is-at Replies", str(sum(arp["replies"].values())))

        if arp.get("duplicate_ips"):
            arp_t.add_row(
                "⚠ Duplicate IPs",
                ", ".join(arp["duplicate_ips"].keys()),
            )

        console.print(arp_t)

    # ================= FINDINGS (AUTO WITH -a) =================
    if a and findings:
        console.print("\n[bold red]Key Findings[/bold red]\n")
        for fnd in findings:
            short_id = fnd["id"].split(":")[0]
            console.print(
                f"• {short_id} – {fnd['title']} [{fnd['severity']}]"
            )

    # ================= EXPORT =================
    base = f"pcapx_{meta['file'].split('.')[0]}"

    if e:
        export_md(result, f"{base}.md")
        console.print(f"[green]✔ Markdown report saved: {base}.md[/green]")

    if j:
        export_iocs_json(result, f"{base}_iocs.json")
        console.print(f"[green]✔ IOC JSON saved: {base}_iocs.json[/green]")


def main():
    app()
