"""Nazar Interactive Shell - Claude Code benzeri interaktif terminal arayuzu."""
import os
import sys
import re
import time
from pathlib import Path

from prompt_toolkit import PromptSession
from prompt_toolkit.completion import Completer, Completion, PathCompleter
from prompt_toolkit.history import FileHistory
from prompt_toolkit.formatted_text import HTML
from prompt_toolkit.styles import Style

from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.syntax import Syntax
from rich.text import Text
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn
from rich import box


BANNER = """[bold cyan]
  ███╗   ██╗ █████╗ ███████╗ █████╗ ██████╗
  ████╗  ██║██╔══██╗╚══███╔╝██╔══██╗██╔══██╗
  ██╔██╗ ██║███████║  ███╔╝ ███████║██████╔╝
  ██║╚██╗██║██╔══██║ ███╔╝  ██╔══██║██╔══██╗
  ██║ ╚████║██║  ██║███████╗██║  ██║██║  ██║
  ╚═╝  ╚═══╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝[/bold cyan]
  [dim]v3.0 - Otonom Guvenlik & Kalite Tarayici[/dim]
"""

HELP_TEXT = """
[bold]BASLANGIC:[/bold]
  Projenizin yolunu yazin, Nazar gerisini halleder:
  [green]nazar> ~/Desktop/MyProject[/green]

[bold]TARAMA:[/bold]
  [cyan]/scan <yol>[/cyan]         Projeyi tara ve analiz et

[bold]SONUCLARI INCELE:[/bold]
  [cyan]/report[/cyan]             Basarisiz testleri goster
  [cyan]/report failed[/cyan]      Sadece basarisizlari goster
  [cyan]/report security[/cyan]    Sadece guvenlik sonuclarini goster
  [cyan]/report appstore[/cyan]    Sadece App Store sonuclarini goster
  [cyan]/detail <no>[/cyan]        Testin detayini + sorunlu kodu goster
  [cyan]/guide <no>[/cyan]         Adim adim duzeltme rehberi

[bold]CIKTI:[/bold]
  [cyan]/export html[/cyan]        Interaktif HTML rapor olustur
  [cyan]/export json[/cyan]        JSON cikti (CI/CD icin)
  [cyan]/export sarif[/cyan]       GitHub Code Scanning formati

[bold]BILGI:[/bold]
  [cyan]/categories[/cyan]         22 kategori ve kontrol sayilari
  [cyan]/stats[/cyan]              Genel istatistikler
  [cyan]/clear[/cyan]              Ekrani temizle
  [cyan]/quit[/cyan]               Cikis

[bold]IPUCLARI:[/bold]
  [dim]Tab[/dim]                  Komut ve dosya yolu otomatik tamamlama
  [dim]Yukari/Asagi ok[/dim]      Onceki komutlari geri cagirma
  [dim]Ctrl+C[/dim]               Islemi iptal et
"""


class NazarCompleter(Completer):
    COMMANDS = ["/scan", "/report", "/detail", "/guide", "/export", "/categories", "/stats", "/clear", "/help", "/quit"]
    FILTERS = ["failed", "passed", "all", "security", "appstore", "code_quality", "ux_text", "ui_component", "cross_file"]
    FORMATS = ["html", "json", "sarif", "junit", "markdown"]

    def __init__(self):
        self.path_completer = PathCompleter(expanduser=True)

    def get_completions(self, document, complete_event):
        text = document.text_before_cursor.strip()
        if text.startswith("/report "):
            sub = text.split(" ", 1)[1]
            for f in self.FILTERS:
                if f.startswith(sub):
                    yield Completion(f, start_position=-len(sub))
        elif text.startswith("/export "):
            sub = text.split(" ", 1)[1]
            for f in self.FORMATS:
                if f.startswith(sub):
                    yield Completion(f, start_position=-len(sub))
        elif text.startswith("/"):
            for cmd in self.COMMANDS:
                if cmd.startswith(text):
                    yield Completion(cmd, start_position=-len(text))
        else:
            yield from self.path_completer.get_completions(document, complete_event)


def _grade(rate):
    for min_r, g in [(97,"A+"),(93,"A"),(90,"A-"),(87,"B+"),(83,"B"),(80,"B-"),(77,"C+"),(73,"C"),(70,"C-"),(67,"D+"),(63,"D"),(60,"D-"),(0,"F")]:
        if rate >= min_r:
            return g
    return "F"


class NazarShell:
    def __init__(self):
        self.console = Console()
        history_dir = Path.home() / ".nazar"
        history_dir.mkdir(exist_ok=True)
        self.session = PromptSession(
            history=FileHistory(str(history_dir / "history")),
            completer=NazarCompleter(),
        )
        self.results = None
        self.plan_data = None
        self.project_path = None

    def run(self):
        self.console.print(BANNER)
        self.console.print("  [bold]158+[/bold] kontrol  |  [bold]22[/bold] kategori  |  [bold]15+[/bold] framework  |  [bold]87[/bold] rehber")
        self.console.print()
        self.console.print("  [green]Baslamak icin taramak istediginiz projenin yolunu yazin:[/green]")
        self.console.print("  [dim]Ornek: ~/Desktop/MyProject[/dim]")
        self.console.print("  [dim]Komutlar icin /help yazin.[/dim]\n")
        while True:
            try:
                text = self.session.prompt(HTML('<style fg="#6366f1"><b>nazar</b></style><style fg="#475569">&gt; </style>'))
                text = text.strip()
                if not text:
                    continue
                self._handle(text)
            except KeyboardInterrupt:
                self.console.print("\n[dim]Iptal edildi.[/dim]")
            except EOFError:
                self.console.print("\n[dim]Gorusuruz![/dim]")
                break

    def _handle(self, text):
        if text.startswith("/"):
            parts = text.split(None, 1)
            cmd, arg = parts[0].lower(), parts[1] if len(parts) > 1 else ""
            cmds = {"/scan": lambda: self._scan(arg), "/report": lambda: self._report(arg), "/detail": lambda: self._detail(arg), "/guide": lambda: self._guide(arg), "/export": lambda: self._export(arg), "/categories": self._categories, "/stats": self._stats, "/clear": self._clear, "/help": lambda: self.console.print(HELP_TEXT), "/quit": lambda: sys.exit(0), "/exit": lambda: sys.exit(0)}
            fn = cmds.get(cmd)
            if fn:
                fn()
            else:
                self.console.print(f"\n[red]  Bilinmeyen komut: {cmd}[/red]")
                self.console.print("[dim]  /help ile tum komutlari gorebilirsiniz.[/dim]\n")
        elif text in (".", "./"):
            self.console.print("\n[yellow]  Mevcut dizini taramak yerine proje yolunu belirtin.[/yellow]")
            self.console.print("[dim]  Ornek: ~/Desktop/MyProject[/dim]\n")
        elif os.path.exists(os.path.expanduser(text)) or text.startswith("/") or text.startswith("~"):
            self._scan(text)
        else:
            self.console.print(f"\n[dim]  '{text}' bulunamadi. Gecerli bir proje yolu veya /help yazin.[/dim]\n")

    def _scan(self, path_str):
        if not path_str:
            self.console.print("\n[yellow]  Hangi projeyi taramak istiyorsunuz?[/yellow]")
            self.console.print("[dim]  Ornek: /scan ~/Desktop/MyProject[/dim]")
            self.console.print("[dim]  Veya direkt dosya yolunu yazin: ~/Desktop/MyProject[/dim]\n")
            return
        path = Path(os.path.expanduser(path_str)).resolve()
        if not path.exists():
            self.console.print(f"\n[red]  Yol bulunamadi: {path}[/red]")
            self.console.print("[dim]  Dosya yolunu kontrol edin. Tab ile otomatik tamamlama kullanabilirsiniz.[/dim]\n")
            return
        self.project_path = str(path)
        start_time = time.time()

        # Faz 1: Tarama
        self.console.print(f"\n[bold cyan][1/3][/bold cyan] [dim]Proje taraniyor...[/dim]")
        from nazar.scanner.project_scanner import ProjectScanner
        from nazar.planner.test_planner import TestPlanner
        from nazar.runners.orchestrator import TestOrchestrator

        scan_start = time.time()
        scanner = ProjectScanner(self.project_path)
        scan_result = scanner.scan()
        scan_dur = time.time() - scan_start
        self.console.print(f"      [green]{scan_result.tech_stack}[/green] | {scan_result.screen_count} ekran | {scan_result.api_endpoint_count} API | {len(scan_result.source_files)} dosya [dim]({scan_dur:.1f}s)[/dim]")

        # Faz 2: Planlama
        self.console.print(f"[bold yellow][2/3][/bold yellow] [dim]Test plani olusturuluyor...[/dim]")
        plan_start = time.time()
        planner = TestPlanner(scan_result)
        plan = planner.create_plan()
        self.plan_data = plan.to_dict()
        plan_dur = time.time() - plan_start
        self.console.print(f"      {plan.total_tests} test planlanidi [dim]({plan_dur:.1f}s)[/dim]")

        # Faz 3: Calistirma - CANLI IZLEME
        self.console.print(f"[bold green][3/3][/bold green] [dim]Testler calistiriliyor...[/dim]\n")
        orchestrator = TestOrchestrator(self.project_path, self.plan_data)
        tests = self.plan_data.get("tests", [])
        self.results = []
        passed = 0
        failed = 0
        current_cat = ""
        cat_results = {}

        from rich.live import Live
        from rich.layout import Layout
        from rich.align import Align

        def build_live_display():
            completed = len(self.results)
            total = len(tests)
            pct = (completed / total * 100) if total > 0 else 0
            elapsed = time.time() - run_start
            rate = (passed / completed * 100) if completed > 0 else 0

            # Progress bar
            bar_w = 30
            filled = int(bar_w * completed / max(total, 1))
            bar = "[green]" + "█" * filled + "[/green][dim]" + "░" * (bar_w - filled) + "[/dim]"

            # Son 5 test
            recent_lines = []
            for r in self.results[-5:]:
                icon = "[green]OK[/green]" if r["passed"] else "[red]XX[/red]"
                name = r["name"][:45]
                dur = f"[dim]{r.get('duration', 0):.2f}s[/dim]"
                recent_lines.append(f"  {icon} {name} {dur}")

            recent_text = "\n".join(recent_lines) if recent_lines else "  [dim]Bekleniyor...[/dim]"

            # Kategori ozet
            cat_lines = []
            for cat, cd in cat_results.items():
                ct = cd["p"] + cd["f"]
                cr = (cd["p"] / ct * 100) if ct > 0 else 0
                ci = "[green]+[/green]" if cr >= 80 else "[yellow]![/yellow]" if cr >= 50 else "[red]-[/red]"
                mini_bar_w = 8
                mini_filled = int(mini_bar_w * cd["p"] / max(ct, 1))
                mini_bar = "[green]" + "█" * mini_filled + "[/green][dim]" + "░" * (mini_bar_w - mini_filled) + "[/dim]"
                running = " [yellow]<<[/yellow]" if cat == current_cat else ""
                cat_lines.append(f"  {ci} {cat[:12]:<12} {cd['p']:>2}/{ct:<2} {mini_bar}{running}")

            cat_text = "\n".join(cat_lines[-10:]) if cat_lines else ""

            display = Text()
            display.append(f"  {bar}  {completed}/{total}  ({pct:.0f}%)  {elapsed:.1f}s\n\n", style="")

            return Panel(
                f"  {bar}  {completed}/{total}  ({pct:.0f}%)  [dim]{elapsed:.1f}s[/dim]\n"
                f"  [green]Gecen: {passed}[/green]  [red]Kalan: {failed}[/red]  [dim]Basari: {rate:.0f}%[/dim]\n\n"
                f"[bold]Son testler:[/bold]\n{recent_text}\n\n"
                f"[bold]Kategoriler:[/bold]\n{cat_text}",
                title="[bold cyan]NAZAR CANLI[/bold cyan]",
                border_style="cyan",
                width=70,
            )

        run_start = time.time()

        with Live(build_live_display(), console=self.console, refresh_per_second=8, transient=True) as live:
            for test in tests:
                test_cat = test.get("type", "other")
                current_cat = test_cat
                if test_cat not in cat_results:
                    cat_results[test_cat] = {"p": 0, "f": 0}

                result = orchestrator._run_test(test)
                self.results.append(result)

                if result["passed"]:
                    passed += 1
                    cat_results[test_cat]["p"] += 1
                else:
                    failed += 1
                    cat_results[test_cat]["f"] += 1

                current_cat = ""
                live.update(build_live_display())

        total_dur = time.time() - start_time
        rate = (passed / len(self.results) * 100) if self.results else 0
        grade = _grade(rate)
        gs = "green" if rate >= 80 else "yellow" if rate >= 60 else "red"

        self.console.print()
        self.console.print(Panel(
            f"[bold {gs}]Not: {grade} ({rate:.0f}%)[/bold {gs}]  |  "
            f"[green]{passed} passed[/green]  |  [red]{failed} failed[/red]  |  "
            f"[dim]{len(self.results)} test  |  {total_dur:.1f}s[/dim]",
            title="[bold cyan]SONUC[/bold cyan]", border_style="cyan",
        ))

        cats = {}
        for r in self.results:
            cat = r.get("type", "other")
            cats.setdefault(cat, {"passed": 0, "failed": 0})
            cats[cat]["passed" if r["passed"] else "failed"] += 1

        self.console.print()
        for cat, d in cats.items():
            total = d["passed"] + d["failed"]
            cr = (d["passed"] / total * 100) if total > 0 else 0
            filled = int(15 * d["passed"] / max(total, 1))
            bar = "[green]" + "█" * filled + "[/green][dim]" + "░" * (15 - filled) + "[/dim]"
            icon = "[green]+[/green]" if cr >= 80 else "[yellow]![/yellow]" if cr >= 50 else "[red]-[/red]"
            rs = f"[green]{cr:.0f}%[/green]" if cr >= 80 else f"[yellow]{cr:.0f}%[/yellow]" if cr >= 50 else f"[red]{cr:.0f}%[/red]"
            self.console.print(f"  {icon} {cat.upper():<16} {d['passed']:>3}/{total:<3} {rs:>6}  {bar}")

        fl = [r for r in self.results if not r["passed"]]
        if fl:
            self.console.print(f"\n[bold]{len(fl)} BASARISIZ TEST:[/bold]")
            for i, r in enumerate(fl[:10], 1):
                pri = r.get("priority", "medium")
                ps = {"critical": "bold red", "high": "bold yellow", "medium": "cyan", "low": "dim"}.get(pri, "dim")
                self.console.print(f"  [dim]#{i:>2}[/dim] [{ps}]{pri.upper():<8}[/{ps}] {r['name'][:50]}")
                self.console.print(f"       [dim]{r['detail'][:60]}[/dim]")
            if len(fl) > 10:
                self.console.print(f"  [dim]...ve {len(fl)-10} daha. /report failed[/dim]")
        self.console.print(f"\n[dim]/report, /detail <no>, /guide <no>, /export html[/dim]")

    def _report(self, filt):
        if not self.results:
            self.console.print("[yellow]Once tarama yapin: /scan <yol>[/yellow]")
            return
        if filt == "failed":
            tests = [r for r in self.results if not r["passed"]]
        elif filt == "passed":
            tests = [r for r in self.results if r["passed"]]
        elif filt and filt != "all":
            tests = [r for r in self.results if r.get("type") == filt]
        else:
            tests = [r for r in self.results if not r["passed"]]
        if not tests:
            self.console.print("[green]Sonuc yok![/green]")
            return
        table = Table(title=f"Sonuclar ({len(tests)})", box=box.ROUNDED)
        table.add_column("#", width=4, style="dim")
        table.add_column("Oncelik", width=8)
        table.add_column("Test", ratio=3)
        table.add_column("Sonuc", width=7)
        table.add_column("Guven", width=6)
        table.add_column("Detay", ratio=2, style="dim")
        for i, r in enumerate(tests, 1):
            pri = r.get("priority", "medium")
            ps = {"critical":"bold red","high":"yellow","medium":"cyan","low":"dim"}.get(pri,"dim")
            st = "[green]PASSED[/green]" if r["passed"] else "[red]FAILED[/red]"
            table.add_row(str(i), f"[{ps}]{pri.upper()}[/{ps}]", r["name"][:45], st, f"{r.get('confidence','?')}%", r.get("detail","")[:35])
        self.console.print(table)

    def _detail(self, num):
        if not self.results:
            self.console.print("[yellow]Once tarama yapin.[/yellow]")
            return
        try:
            idx = int(num) - 1
        except (ValueError, TypeError):
            self.console.print("[red]/detail 1 seklinde girin.[/red]")
            return
        fl = [r for r in self.results if not r["passed"]]
        if idx < 0 or idx >= len(fl):
            self.console.print(f"[red]1-{len(fl)} arasi girin.[/red]")
            return
        r = fl[idx]
        self.console.print(Panel(f"[bold]{r['name']}[/bold]\n\nOncelik: [bold]{r.get('priority','').upper()}[/bold] | Guven: [bold]{r.get('confidence','?')}%[/bold]\nKategori: {r.get('type','').upper()}\n\n[bold]Detay:[/bold] {r.get('detail','')}", title=f"[bold cyan]#{idx+1}[/bold cyan]", border_style="cyan"))
        detail = r.get("detail", "")
        m = re.search(r'([a-zA-Z0-9_/\-\.()]+\.[a-zA-Z]+):(\d+)', detail)
        if m and self.project_path:
            fp, ln = m.group(1), int(m.group(2))
            full = os.path.join(self.project_path, fp)
            if os.path.exists(full):
                try:
                    lines = open(full, errors="ignore").readlines()
                    s, e = max(0, ln-3), min(len(lines), ln+3)
                    code = "".join(lines[s:e])
                    lang = "typescript" if fp.endswith((".ts",".tsx")) else "python" if fp.endswith(".py") else "javascript"
                    self.console.print(Panel(Syntax(code, lang, theme="monokai", line_numbers=True, start_line=s+1, highlight_lines={ln}), title=f"[bold]{fp}[/bold]", border_style="red"))
                except Exception:
                    pass
        self.console.print(f"\n[dim]Rehber: /guide {idx+1}[/dim]")

    def _guide(self, num):
        if not self.results:
            self.console.print("[yellow]Once tarama yapin.[/yellow]")
            return
        try:
            idx = int(num) - 1
        except (ValueError, TypeError):
            self.console.print("[red]/guide 1 seklinde girin.[/red]")
            return
        fl = [r for r in self.results if not r["passed"]]
        if idx < 0 or idx >= len(fl):
            self.console.print(f"[red]1-{len(fl)} arasi girin.[/red]")
            return
        r = fl[idx]
        guide = r.get("guide")
        if not guide:
            fix = r.get("how_to_fix")
            if fix:
                self.console.print(f"\n[bold red]SORUN:[/bold red] {fix.get('sorun','')}")
                self.console.print(f"[bold green]COZUM:[/bold green] {fix.get('cozum','')}")
                self.console.print(f"[bold cyan]QUICK FIX:[/bold cyan] {fix.get('quick_fix','')}")
            else:
                self.console.print("[yellow]Bu test icin rehber yok.[/yellow]")
            return
        ct = Text()
        ct.append(f"\n  RISK: ", style="bold red")
        ct.append(f"{guide['risk']}\n\n")
        ct.append(f"  Ne Oluyor: ", style="bold")
        ct.append(f"{guide['what']}\n")
        ct.append(f"  Neden Onemli: ", style="bold")
        ct.append(f"{guide['why']}\n")
        self.console.print(Panel(ct, title=f"[bold yellow]{guide['title']}[/bold yellow]", border_style="yellow"))
        steps = guide.get("steps", [])
        if steps:
            self.console.print("\n[bold]  ADIM ADIM:[/bold]")
            for i, s in enumerate(steps, 1):
                self.console.print(f"  [cyan]{i}.[/cyan] {s}")
        before, after = guide.get("before", ""), guide.get("after", "")
        if before and after:
            self.console.print()
            self.console.print(Panel(before, title="[red]ONCE[/red]", border_style="red"))
            self.console.print(Panel(after, title="[green]SONRA[/green]", border_style="green"))
        if guide.get("warning"):
            self.console.print(f"\n[yellow]  UYARI: {guide['warning']}[/yellow]")
        if guide.get("tools"):
            self.console.print(f"[dim]  Onerilen: {', '.join(guide['tools'])}[/dim]")
        self.console.print()

    def _export(self, fmt_str):
        if not self.results:
            self.console.print("[yellow]Once tarama yapin.[/yellow]")
            return
        parts = fmt_str.split(None, 1)
        fmt = parts[0] if parts else "html"
        out = parts[1] if len(parts) > 1 else None
        if fmt == "html":
            out = out or "nazar-report.html"
            from nazar.reporter.html_reporter import HTMLReporter
            HTMLReporter().generate(self.results, self.plan_data or {}, out)
        elif fmt == "json":
            out = out or "nazar-report.json"
            from nazar.reporters.json_reporter import JSONReporter
            JSONReporter().generate(self.results, self.plan_data or {}, out)
        elif fmt == "sarif":
            out = out or "nazar-report.sarif"
            from nazar.reporters.sarif_reporter import SARIFReporter
            SARIFReporter().generate(self.results, self.plan_data or {}, out)
        elif fmt == "markdown":
            out = out or "nazar-report.md"
            from nazar.reporters.markdown_reporter import MarkdownReporter
            MarkdownReporter().generate(self.results, self.plan_data or {}, out)
        else:
            self.console.print(f"[red]Format: html/json/sarif/markdown[/red]")
            return
        self.console.print(f"[green]Rapor olusturuldu: {out}[/green]")

    def _categories(self):
        table = Table(title="Nazar v3.0 Kategorileri", box=box.ROUNDED)
        table.add_column("Kategori", style="cyan", width=18)
        table.add_column("Kontrol", justify="center", width=8)
        table.add_column("Aciklama", ratio=3)
        cats = [
            ("Security", "63", "50+ secret, OWASP, crypto, supply chain"),
            ("App Store", "32", "Privacy manifest, IAP, Sign in with Apple"),
            ("Play Store", "10", "targetSdk, exported, ProGuard, permissions"),
            ("SCA", "7", "npm/pip/go audit, typosquatting, lisans"),
            ("AST Analysis", "6", "Python AST: eval, bare except, mutable default"),
            ("Taint Tracking", "5", "SQL injection, XSS, command injection akisi"),
            ("Code Quality", "16", "Complexity, dead code, smells"),
            ("UI Component", "10", "a11y, touch target, dark mode"),
            ("UX Text", "8", "Yazim, tutarlilik, i18n"),
            ("Cross-File", "7", "Dead export, orphan, circular import"),
            ("API", "4", "Erisilebilirlik, response"),
            ("Git", "4", "gitignore, buyuk dosya"),
            ("YAML Rules", "3", "Semgrep benzeri ozel kural motoru"),
            ("Type Safety", "3", "any, ts-ignore"),
            ("Error Handling", "3", "Bos catch, async"),
            ("Performance", "3", "Buyuk dosya/gorsel"),
            ("Documentation", "3", "README, CHANGELOG"),
            ("Naming", "3", "Dosya isimleri"),
            ("Dependency", "3", "Vulnerability"),
            ("Accessibility", "2", "testID, label"),
            ("Docker", "2", "Image, secret"),
        ]
        for n, c, d in cats:
            table.add_row(n, c, d)
        table.add_row("[bold]TOPLAM[/bold]", "[bold]158+[/bold]", "")
        self.console.print(table)

    def _clear(self):
        # Statik 'clear' komutu - kullanici girdisi yok, guvenli
        import subprocess
        subprocess.run(['clear'], check=False)
        self.console.print(BANNER)
        self.console.print("  [bold]158+[/bold] kontrol  |  [bold]22[/bold] kategori  |  [bold]15+[/bold] framework  |  [bold]87[/bold] rehber\n")

    def _stats(self):
        from nazar.guides.registry import GuideRegistry
        from nazar.runners.confidence import CONFIDENCE_SCORES
        table = Table(title="Nazar v3.0", box=box.ROUNDED)
        table.add_column("Metrik", style="cyan")
        table.add_column("Deger", style="green")
        table.add_row("Kontrol", "158+")
        table.add_row("Kategori", "22")
        table.add_row("Guide", str(len(GuideRegistry.get_all())))
        table.add_row("Confidence", str(len(CONFIDENCE_SCORES)))
        table.add_row("Framework", "15+")
        table.add_row("Format", "5 (HTML, JSON, SARIF, Markdown, JUnit)")
        table.add_row("Moduller", "SCA, AST, Taint, YAML Rules, App/Play Store")
        if self.results:
            p = sum(1 for r in self.results if r["passed"])
            f = len(self.results) - p
            table.add_row("", "")
            table.add_row("[bold]Son Tarama[/bold]", f"[bold]{self.project_path}[/bold]")
            table.add_row("Gecen/Kalan", f"[green]{p}[/green] / [red]{f}[/red]")
        self.console.print(table)
