"""Rule inheritance logic for ProjectService."""

from __future__ import annotations

from noteflow.domain.entities.project import (
    SYSTEM_DEFAULTS,
    EffectiveRules,
    ExportRules,
    ProjectSettings,
    TriggerRules,
)
from noteflow.domain.identity import WorkspaceSettings


class RuleInheritanceMixin:
    """Compute effective rules from system, workspace, and project settings."""

    def get_effective_rules(
        self,
        workspace_settings: WorkspaceSettings | None,
        project_settings: ProjectSettings | None,
    ) -> EffectiveRules:
        """Compute effective rules by merging inheritance chain.

        Resolution order: system defaults → workspace → project
        Coalesce logic:
        - None = inherit from parent
        - [] (empty list) = explicitly cleared (override with empty)
        - value = override parent with this value

        Args:
            workspace_settings: Workspace-level settings (optional).
            project_settings: Project-level settings (optional).

        Returns:
            Fully resolved rules with no None values.
        """
        # Start with system defaults
        export = self._merge_export_rules(
            SYSTEM_DEFAULTS.export,
            workspace_settings.export_rules if workspace_settings else None,
            project_settings.export_rules if project_settings else None,
        )

        trigger = self._merge_trigger_rules(
            SYSTEM_DEFAULTS.trigger,
            workspace_settings.trigger_rules if workspace_settings else None,
            project_settings.trigger_rules if project_settings else None,
        )

        # Merge scalar settings
        rag_enabled = self._coalesce(
            SYSTEM_DEFAULTS.rag_enabled,
            workspace_settings.rag_enabled if workspace_settings else None,
            project_settings.rag_enabled if project_settings else None,
        )

        default_template = self._coalesce(
            SYSTEM_DEFAULTS.default_summarization_template,
            workspace_settings.default_summarization_template if workspace_settings else None,
            project_settings.default_summarization_template if project_settings else None,
        )

        return EffectiveRules(
            export=export,
            trigger=trigger,
            rag_enabled=rag_enabled,
            default_summarization_template=default_template,
        )

    def _merge_export_rules(
        self,
        system: ExportRules,
        workspace: ExportRules | None,
        project: ExportRules | None,
    ) -> ExportRules:
        """Merge export rules through inheritance chain.

        Args:
            system: System default export rules.
            workspace: Workspace-level override (optional).
            project: Project-level override (optional).

        Returns:
            Merged export rules.
        """
        default_format = self._coalesce(
            system.default_format,
            workspace.default_format if workspace else None,
            project.default_format if project else None,
        )
        include_audio = self._coalesce(
            system.include_audio,
            workspace.include_audio if workspace else None,
            project.include_audio if project else None,
        )
        include_timestamps = self._coalesce(
            system.include_timestamps,
            workspace.include_timestamps if workspace else None,
            project.include_timestamps if project else None,
        )
        template_id = self._coalesce(
            system.template_id,
            workspace.template_id if workspace else None,
            project.template_id if project else None,
        )

        return ExportRules(
            default_format=default_format,
            include_audio=include_audio,
            include_timestamps=include_timestamps,
            template_id=template_id,
        )

    def _merge_trigger_rules(
        self,
        system: TriggerRules,
        workspace: TriggerRules | None,
        project: TriggerRules | None,
    ) -> TriggerRules:
        """Merge trigger rules through inheritance chain.

        For list fields, empty list [] means "explicitly cleared" and overrides parent.
        None means "inherit from parent".

        Args:
            system: System default trigger rules.
            workspace: Workspace-level override (optional).
            project: Project-level override (optional).

        Returns:
            Merged trigger rules.
        """
        auto_start = self._coalesce(
            system.auto_start_enabled,
            workspace.auto_start_enabled if workspace else None,
            project.auto_start_enabled if project else None,
        )

        # For lists, empty list is a valid override (clears parent)
        calendar_patterns = self._coalesce_list(
            system.calendar_match_patterns,
            workspace.calendar_match_patterns if workspace else None,
            project.calendar_match_patterns if project else None,
        )

        app_patterns = self._coalesce_list(
            system.app_match_patterns,
            workspace.app_match_patterns if workspace else None,
            project.app_match_patterns if project else None,
        )

        return TriggerRules(
            auto_start_enabled=auto_start,
            calendar_match_patterns=calendar_patterns,
            app_match_patterns=app_patterns,
        )

    @staticmethod
    def _coalesce[T](system: T, workspace: T | None, project: T | None) -> T:
        """Coalesce values through inheritance chain.

        Return the most specific non-None value.

        Args:
            system: System default (always non-None).
            workspace: Workspace-level value (optional).
            project: Project-level value (optional).

        Returns:
            Most specific non-None value.
        """
        if project is not None:
            return project
        if workspace is not None:
            return workspace
        return system

    @staticmethod
    def _coalesce_list[T](
        system: list[T] | None,
        workspace: list[T] | None,
        project: list[T] | None,
    ) -> list[T] | None:
        """Coalesce list values with explicit empty override.

        Empty list [] is a valid override (clears parent).
        None means inherit from parent.

        Args:
            system: System default (may be None or list).
            workspace: Workspace-level value (optional).
            project: Project-level value (optional).

        Returns:
            Most specific value (None, [], or populated list).
        """
        if project is not None:
            return project
        if workspace is not None:
            return workspace
        return system
