"""DetectStateService - Detect current project state.

Contract: CNT-T2-SVC-004
Traceability: UC-004
"""

from dataclasses import dataclass
from pathlib import Path


@dataclass(frozen=True, slots=True)
class ProjectState:
    """Represents the current state of a LAIDA project."""

    last_completed_phase: int | None
    last_completed_step: int | None
    next_phase: int
    next_step: int
    is_complete: bool

    @property
    def has_started(self) -> bool:
        """Check if project has any completed steps."""
        return self.last_completed_phase is not None

    def __str__(self) -> str:
        """Return human-readable state description."""
        if self.is_complete:
            return "Project complete (Phase 4 Step 3)"
        if not self.has_started:
            return "Project not started (next: Phase 0 Step 0)"
        return (
            f"Last: Phase {self.last_completed_phase} Step {self.last_completed_step}, "
            f"Next: Phase {self.next_phase} Step {self.next_step}"
        )


class DetectStateService:
    """Service for detecting current project state."""

    STEP_NAMES = {
        0: {
            0: "step0_profiling",
            1: "step1_foundation",
            2: "step2_capabilities",
            3: "step3_blueprint",
        },
        1: {
            0: "step0_traceability",
            1: "step1_specification",
            2: "step2_validation",
            3: "step3_assembly",
        },
        2: {
            0: "step0_cot_architecture",
            1: "step1_file_structure",
            2: "step2_validation",
            3: "step3_assembly",
        },
        3: {
            0: "step0_foundations",
            1: "step1_contracts",
            2: "step2_validation",
            3: "step3_assembly",
        },
        4: {
            0: "step0_environment_scaffolding",
            1: "step1_domain_application",
            2: "step2_infrastructure",
            3: "step3_verification_release",
        },
    }

    def detect(self, project_path: Path) -> ProjectState:
        """Detect current project state by scanning outputs directory.

        Args:
            project_path: Path to the LAIDA project

        Returns:
            ProjectState with current progress
        """
        outputs_dir = project_path / "outputs"

        if not outputs_dir.exists():
            return ProjectState(
                last_completed_phase=None,
                last_completed_step=None,
                next_phase=0,
                next_step=0,
                is_complete=False,
            )

        last_phase: int | None = None
        last_step: int | None = None

        # Scan phases 0-4
        for phase in range(5):
            phase_dir = outputs_dir / f"phase{phase}"
            if not phase_dir.exists():
                break

            # Scan steps 0-3
            for step in range(4):
                step_pattern = f"step{step}_*"
                step_dirs = list(phase_dir.glob(step_pattern))

                if step_dirs:
                    step_dir = step_dirs[0]
                    index_file = step_dir / "_index.yaml"

                    if index_file.exists():
                        last_phase = phase
                        last_step = step

        # Calculate next step
        if last_phase is None:
            next_phase, next_step = 0, 0
        elif last_phase == 4 and last_step == 3:
            return ProjectState(
                last_completed_phase=4,
                last_completed_step=3,
                next_phase=4,
                next_step=3,
                is_complete=True,
            )
        elif last_step == 3:
            next_phase = last_phase + 1
            next_step = 0
        else:
            next_phase = last_phase
            next_step = (last_step or 0) + 1

        return ProjectState(
            last_completed_phase=last_phase,
            last_completed_step=last_step,
            next_phase=next_phase,
            next_step=next_step,
            is_complete=False,
        )

    def get_step_name(self, phase: int, step: int) -> str:
        """Get the step directory name.

        Args:
            phase: Phase number (0-4)
            step: Step number (0-3)

        Returns:
            Step directory name
        """
        return self.STEP_NAMES.get(phase, {}).get(step, f"step{step}_unknown")
