import logging
import uuid
from pathlib import Path
from typing import Any

from ...clients.repo import RelaceRepoClient
from .state import get_current_git_info, load_sync_state

logger = logging.getLogger(__name__)


def cloud_info_logic(
    client: RelaceRepoClient,
    base_dir: str,
) -> dict[str, Any]:
    """Get current repository sync status and cloud info.

    Integrates: local sync state + current git ref + list summary (if cloud repo exists)

    Args:
        client: RelaceRepoClient instance.
        base_dir: Base directory of the repository.

    Returns:
        Dict containing:
        - repo_name: Repository name (derived from base_dir)
        - local: Current local git state
        - synced: Last synced state (from local cache)
        - cloud: Cloud repo info (if found in list)
        - status: Sync status and recommended action
        - error: Error message if failed (optional)
    """
    trace_id = str(uuid.uuid4())[:8]
    repo_name = Path(base_dir).name
    logger.info("[%s] Getting cloud info for '%s'", trace_id, repo_name)

    try:
        # Get current git info
        current_branch, current_head = get_current_git_info(base_dir)

        # Load local sync state
        sync_state = load_sync_state(repo_name)

        # Build local info
        local_info = {
            "git_branch": current_branch,
            "git_head": current_head[:8] if current_head else "",
        }

        # Build synced info from local state
        synced_info = None
        if sync_state:
            synced_info = {
                "repo_id": sync_state.repo_id,
                "repo_head": sync_state.repo_head[:8] if sync_state.repo_head else "",
                "git_branch": sync_state.git_branch,
                "git_head": sync_state.git_head_sha[:8] if sync_state.git_head_sha else "",
                "last_sync": sync_state.last_sync,
                "tracked_files": len(sync_state.files),
                "skipped_files": len(sync_state.skipped_files),
            }

        # Try to find cloud repo in list
        cloud_info = None
        try:
            repos = client.list_repos(trace_id=trace_id)
            for repo in repos:
                metadata = repo.get("metadata") or {}
                name = metadata.get("name") or repo.get("name")
                if name == repo_name:
                    cloud_info = {
                        "repo_id": repo.get("repo_id") or repo.get("id"),
                        "auto_index": repo.get("auto_index"),
                        "created_at": repo.get("created_at"),
                        "updated_at": repo.get("updated_at"),
                    }
                    break
        except Exception as exc:
            logger.warning("[%s] Failed to fetch cloud repos: %s", trace_id, exc)

        # Determine status
        ref_changed = False
        needs_sync = False
        recommended_action = None

        if sync_state and current_head:
            old_head = sync_state.git_head_sha
            if old_head and old_head != current_head:
                ref_changed = True
                needs_sync = True
                recommended_action = (
                    "Git HEAD changed since last sync. "
                    "Run cloud_sync() for safe sync, or "
                    "cloud_sync(force=True, mirror=True) to fully align with current branch."
                )
        elif not sync_state:
            needs_sync = True
            recommended_action = "No sync state found. Run cloud_sync() to upload codebase."

        status_info = {
            "ref_changed": ref_changed,
            "needs_sync": needs_sync,
            "recommended_action": recommended_action,
        }

        logger.info(
            "[%s] Info retrieved: synced=%s, cloud=%s, ref_changed=%s",
            trace_id,
            synced_info is not None,
            cloud_info is not None,
            ref_changed,
        )

        return {
            "repo_name": repo_name,
            "local": local_info,
            "synced": synced_info,
            "cloud": cloud_info,
            "status": status_info,
        }

    except Exception as exc:
        logger.error("[%s] Cloud info failed: %s", trace_id, exc)
        return {
            "repo_name": repo_name,
            "local": None,
            "synced": None,
            "cloud": None,
            "status": None,
            "error": str(exc),
        }
