from __future__ import annotations

import platform
import sys
from dataclasses import dataclass, field
from pathlib import Path

from .deferred_init import DeferredInitResult, run_deferred_init
from .prefetch import PrefetchResult, start_keychain_prefetch, start_mdm_raw_read, start_project_scan
from .release_notes import check_for_release_notes


MIN_PYTHON_VERSION: tuple[int, int] = (3, 10)


@dataclass(frozen=True)
class RuntimeRequirementCheck:
    name: str
    ok: bool
    detail: str


def check_runtime_requirements() -> tuple[RuntimeRequirementCheck, ...]:
    checks: list[RuntimeRequirementCheck] = []
    py_major, py_minor = sys.version_info[:2]
    py_ok = (py_major, py_minor) >= MIN_PYTHON_VERSION
    checks.append(RuntimeRequirementCheck(
        name='python_version',
        ok=py_ok,
        detail=(
            f'Python {py_major}.{py_minor} >= {MIN_PYTHON_VERSION[0]}.{MIN_PYTHON_VERSION[1]}'
            if py_ok
            else f'Python {py_major}.{py_minor} is below required '
                 f'{MIN_PYTHON_VERSION[0]}.{MIN_PYTHON_VERSION[1]}'
        ),
    ))
    impl = platform.python_implementation()
    checks.append(RuntimeRequirementCheck(
        name='python_implementation',
        ok=True,
        detail=impl,
    ))
    machine = platform.machine() or 'unknown'
    system = platform.system() or 'unknown'
    checks.append(RuntimeRequirementCheck(
        name='platform',
        ok=True,
        detail=f'{system} on {machine}',
    ))
    return tuple(checks)


def _read_package_version() -> str:
    try:
        from importlib.metadata import version

        return version('claw-code-agent')
    except Exception:
        return '0.0.0'


@dataclass(frozen=True)
class WorkspaceSetup:
    python_version: str
    implementation: str
    platform_name: str
    test_command: str = 'python3 -m unittest discover -s tests -v'

    def startup_steps(self) -> tuple[str, ...]:
        return (
            'start top-level prefetch side effects',
            'build workspace context',
            'load mirrored command snapshot',
            'load mirrored tool snapshot',
            'prepare parity audit hooks',
            'apply trust-gated deferred init',
        )


@dataclass(frozen=True)
class SetupReport:
    setup: WorkspaceSetup
    prefetches: tuple[PrefetchResult, ...]
    deferred_init: DeferredInitResult
    trusted: bool
    cwd: Path
    runtime_checks: tuple[RuntimeRequirementCheck, ...] = field(default_factory=tuple)
    release_notes: tuple[str, ...] = field(default_factory=tuple)

    def has_blocking_issues(self) -> bool:
        return any(not check.ok for check in self.runtime_checks)

    def as_markdown(self) -> str:
        lines = [
            '# Setup Report',
            '',
            f'- Python: {self.setup.python_version} ({self.setup.implementation})',
            f'- Platform: {self.setup.platform_name}',
            f'- Trusted mode: {self.trusted}',
            f'- CWD: {self.cwd}',
            '',
            'Runtime checks:',
            *(
                f'- {check.name}: {"ok" if check.ok else "FAIL"} — {check.detail}'
                for check in self.runtime_checks
            ),
            '',
            'Prefetches:',
            *(f'- {prefetch.name}: {prefetch.detail}' for prefetch in self.prefetches),
            '',
            'Deferred init:',
            *self.deferred_init.as_lines(),
        ]
        if self.release_notes:
            lines.extend(['', 'Release notes (newer than last seen):'])
            lines.extend(f'- {note}' for note in self.release_notes)
        return '\n'.join(lines)


def build_workspace_setup() -> WorkspaceSetup:
    return WorkspaceSetup(
        python_version='.'.join(str(part) for part in sys.version_info[:3]),
        implementation=platform.python_implementation(),
        platform_name=platform.platform(),
    )


def run_setup(
    cwd: Path | None = None,
    trusted: bool = True,
    last_seen_version: str | None = None,
) -> SetupReport:
    root = cwd or Path(__file__).resolve().parent.parent
    prefetches = [
        start_mdm_raw_read(),
        start_keychain_prefetch(),
        start_project_scan(root),
    ]
    release_notes_payload = check_for_release_notes(
        current_version=_read_package_version(),
        last_seen_version=last_seen_version,
        cwd=root,
    )
    return SetupReport(
        setup=build_workspace_setup(),
        prefetches=tuple(prefetches),
        deferred_init=run_deferred_init(trusted=trusted),
        trusted=trusted,
        cwd=root,
        runtime_checks=check_runtime_requirements(),
        release_notes=tuple(release_notes_payload['releaseNotes']),
    )
