import json
import os
from typing import Dict, Any, Optional


class IndexingState:
    """
    Manages the indexing state of the documentation repository.
    """
    INDEXING_IN_PROGRESS = "INDEXING_IN_PROGRESS"
    INDEXING_COMPLETE = "INDEXING_COMPLETE"

    def __init__(self, repo_path: str):
        """
        Initializes the IndexingState with the path to the repository.

        :param repo_path: The absolute path to the documentation repository.
        """
        self.state_file_path = os.path.join(repo_path, ".index_state.json")

    def read_state(self) -> Optional[Dict[str, Any]]:
        """
        Reads the indexing state from the .index_state.json file.

        :return: A dictionary representing the state, or None if the file does not exist.
        """
        if not os.path.exists(self.state_file_path):
            return None
        try:
            with open(self.state_file_path, "r") as f:
                return json.load(f)
        except (IOError, json.JSONDecodeError):
            return None

    def write_state(self, status: str, commit_hash: Optional[str] = None):
        """
        Writes the indexing state to the .index_state.json file.

        :param status: The indexing status, e.g., "INDEXING_IN_PROGRESS".
        :param commit_hash: The commit hash that was indexed.
        """
        state = {"status": status}
        if commit_hash:
            state["indexed_commit_hash"] = commit_hash
        with open(self.state_file_path, "w") as f:
            json.dump(state, f, indent=2)

    def set_indexing_in_progress(self):
        """
        Sets the indexing state to "INDEXING_IN_PROGRESS".
        """
        self.write_state(self.INDEXING_IN_PROGRESS)

    def set_indexing_complete(self, commit_hash: str):
        """
        Sets the indexing state to "INDEXING_COMPLETE" with the given commit hash.

        :param commit_hash: The commit hash that was successfully indexed.
        """
        self.write_state(self.INDEXING_COMPLETE, commit_hash)

    def is_indexing_in_progress(self) -> bool:
        """
        Checks if the indexing state is "INDEXING_IN_PROGRESS".

        :return: True if the state is "INDEXING_IN_PROGRESS", False otherwise.
        """
        state = self.read_state()
        return state and state.get("status") == self.INDEXING_IN_PROGRESS

    def get_indexed_commit_hash(self) -> Optional[str]:
        """
        Gets the indexed commit hash from the state file.

        :return: The commit hash if the state is "INDEXING_COMPLETE", None otherwise.
        """
        state = self.read_state()
        if state and state.get("status") == self.INDEXING_COMPLETE:
            return state.get("indexed_commit_hash")
        return None
