"""GitHub API operations for shōmei."""

import base64
import requests
from rich.console import Console

console = Console()


def create_github_repo(username, repo_name, token, private=False):
    """
    Create a fresh repository on GitHub.

    Args:
        username: GitHub username
        repo_name: Name for the new repository
        token: GitHub personal access token
        private: Whether to make the repo private (default: False)

    Returns:
        bool: True if repo was created or already exists, False on error
    """
    url = "https://api.github.com/user/repos"
    headers = {
        "Authorization": f"token {token}",
        "Accept": "application/vnd.github.v3+json"
    }
    data = {
        "name": repo_name,
        "description": "Generated by shōmei: mirrors verified contributions without code",
        "private": private,
        "auto_init": True  # creates main branch automatically
    }

    response = requests.post(url, json=data, headers=headers, timeout=10)

    if response.status_code == 201:
        console.print(f"[green]repo created: github.com/{username}/{repo_name}[/green]")
        return True
    elif response.status_code == 422:
        # repo already exists, that's cool
        console.print(f"[yellow]!!! repo already exists, we'll add commits to it[/yellow]")
        return True
    else:
        console.print(f"[red]!!! couldn't create repo: {response.json().get('message', 'unknown error')}[/red]")
        return False


def get_main_branch_sha(username, repo_name, token):
    """
    Get the current SHA of the main branch.

    Args:
        username: GitHub username
        repo_name: Repository name
        token: GitHub personal access token

    Returns:
        str or None: The SHA of the main branch HEAD, or None if not found
    """
    url = f"https://api.github.com/repos/{username}/{repo_name}/git/refs/heads/main"
    headers = {
        "Authorization": f"token {token}",
        "Accept": "application/vnd.github.v3+json"
    }

    response = requests.get(url, headers=headers, timeout=10)
    if response.status_code == 200:
        return response.json()['object']['sha']
    return None


def create_empty_commit(username, repo_name, date, token, parent_sha=None):
    """
    Create an empty commit via GitHub API.

    This is where the magic happens - we're creating commits with your dates
    but zero code. Just timestamps. Your contribution graph gets updated,
    but no company IP leaves your machine.

    Args:
        username: GitHub username
        repo_name: Repository name
        date: datetime object for the commit timestamp
        token: GitHub personal access token
        parent_sha: SHA of the parent commit (None for initial commit)

    Returns:
        tuple: (commit_sha: str or None, error_message: str or None)
    """
    headers = {
        "Authorization": f"token {token}",
        "Accept": "application/vnd.github.v3+json"
    }

    try:
        # step 1: get the current tree (or create an empty one)
        if parent_sha:
            # get the tree from the parent commit
            commit_url = f"https://api.github.com/repos/{username}/{repo_name}/git/commits/{parent_sha}"
            commit_response = requests.get(commit_url, headers=headers, timeout=10)
            if commit_response.status_code == 200:
                tree_sha = commit_response.json()['tree']['sha']
            else:
                return None, "couldn't get parent tree"
        else:
            # create an empty tree
            tree_url = f"https://api.github.com/repos/{username}/{repo_name}/git/trees"
            tree_response = requests.post(tree_url, json={"tree": []}, headers=headers, timeout=10)
            if tree_response.status_code != 201:
                return None, "couldn't create tree"
            tree_sha = tree_response.json()['sha']

        # step 2: create the commit
        commit_url = f"https://api.github.com/repos/{username}/{repo_name}/git/commits"
        commit_data = {
            "message": "ci(shōmei): sync work contribution",
            "tree": tree_sha,
            "parents": [parent_sha] if parent_sha else [],
            "author": {
                "name": username,
                "email": f"{username}@users.noreply.github.com",
                "date": date.strftime('%Y-%m-%dT%H:%M:%SZ')
            },
            "committer": {
                "name": username,
                "email": f"{username}@users.noreply.github.com",
                "date": date.strftime('%Y-%m-%dT%H:%M:%SZ')
            }
        }

        commit_response = requests.post(commit_url, json=commit_data, headers=headers, timeout=10)

        if commit_response.status_code == 201:
            return commit_response.json()['sha'], None
        else:
            return None, commit_response.json().get('message', 'unknown error')

    except requests.exceptions.Timeout:
        return None, "request timeout"
    except Exception as e:
        return None, str(e)


def update_branch_ref(username, repo_name, token, commit_sha):
    """
    Update the main branch to point to a new commit.

    Args:
        username: GitHub username
        repo_name: Repository name
        token: GitHub personal access token
        commit_sha: SHA of the commit to point the branch to

    Returns:
        bool: True if successful, False otherwise
    """
    url = f"https://api.github.com/repos/{username}/{repo_name}/git/refs/heads/main"
    headers = {
        "Authorization": f"token {token}",
        "Accept": "application/vnd.github.v3+json"
    }
    data = {
        "sha": commit_sha,
        "force": True
    }

    response = requests.patch(url, json=data, headers=headers, timeout=10)
    return response.status_code == 200


def update_repo_readme(username, repo_name, token, content):
    """
    Update or create the README.md file in the repository.

    Args:
        username: GitHub username
        repo_name: Repository name
        token: GitHub personal access token
        content: Markdown content for the README

    Returns:
        bool: True if successful, False otherwise
    """
    headers = {
        "Authorization": f"token {token}",
        "Accept": "application/vnd.github.v3+json"
    }

    try:
        # first, get the current README to get its SHA (needed for update)
        readme_url = f"https://api.github.com/repos/{username}/{repo_name}/contents/README.md"
        response = requests.get(readme_url, headers=headers, timeout=10)

        if response.status_code == 200:
            # README exists, update it
            current_sha = response.json()['sha']
            update_data = {
                "message": "docs(shōmei): update README with contribution details",
                "content": base64.b64encode(content.encode('utf-8')).decode('utf-8'),
                "sha": current_sha
            }

            update_response = requests.put(readme_url, json=update_data, headers=headers, timeout=10)
            return update_response.status_code == 200
        else:
            # README doesn't exist, create it
            create_data = {
                "message": "docs(shōmei): add README with contribution details",
                "content": base64.b64encode(content.encode('utf-8')).decode('utf-8')
            }
            create_response = requests.put(readme_url, json=create_data, headers=headers, timeout=10)
            return create_response.status_code == 201

    except Exception:
        return False
