# git/operations/merge.py
import git
import logging
import os
from typing import Dict, Any
from ..status.status import GitStatusManager

logger = logging.getLogger(__name__)


def finalize_merge(repo) -> Dict[str, Any]:
    """
    Finalize a merge by committing all staged files after conflict resolution.
    """
    try:
        if not os.path.exists(os.path.join(repo.git_dir, 'MERGE_HEAD')):
            return {
                'success': False,
                'error': 'Not currently in a merge state'
            }

        # Get unmerged files
        unmerged_files = []
        status = repo.git.status('--porcelain', '-z').split('\0')
        for item in status:
            if item and len(item) >= 4:
                x, y, file_path = item[0], item[1], item[3:]
                if 'U' in (x, y):
                    unmerged_files.append(file_path)

        # Force update the index for unmerged files
        for file_path in unmerged_files:
            # Remove from index first
            try:
                repo.git.execute(['git', 'reset', '--', file_path])
            except git.GitCommandError:
                pass

            # Add back to index
            try:
                repo.git.execute(['git', 'add', '--', file_path])
            except git.GitCommandError as e:
                logger.error(f"Error adding file {file_path}: {str(e)}")
                return {
                    'success': False,
                    'error': f"Failed to stage resolved file {file_path}"
                }

        # Create commit message
        commit_message = "Merge complete: resolved conflicts"

        # Commit
        try:
            repo.git.commit('-m', commit_message)
            logger.info("Successfully finalized merge")

            # Update remote status after merge
            repo_path = repo.working_dir
            status_manager = GitStatusManager.get_instance(repo_path)
            if status_manager:
                status_manager.update_remote_status()

            return {'success': True, 'message': 'Merge completed successfully'}
        except git.GitCommandError as e:
            logger.error(f"Git command error during commit: {str(e)}")
            return {
                'success': False,
                'error': f"Failed to commit merge: {str(e)}"
            }

    except Exception as e:
        logger.error(f"Failed to finalize merge: {str(e)}")
        return {
            'success': False,
            'error': f"Failed to finalize merge: {str(e)}"
        }


def abort_merge(repo_path):
    try:
        repo = git.Repo(repo_path)

        # Try aborting the merge using git merge --abort
        try:
            repo.git.execute(['git', 'merge', '--abort'])
            return True, "Merge aborted successfully"
        except git.GitCommandError as e:
            logger.warning(
                "Error aborting merge with 'git merge --abort'. Trying 'git reset --hard'."
            )

        # If git merge --abort fails, try resetting to the previous commit using git reset --hard
        try:
            repo.git.execute(['git', 'reset', '--hard'])
            return True, "Merge aborted and repository reset to the previous commit"
        except git.GitCommandError as e:
            logger.exception(
                "Error resetting repository with 'git reset --hard'")
            return False, str(e)

    except Exception as e:
        logger.exception("Unexpected error aborting merge")
        return False, str(e)
