import os, json,hashlib
from fastapi import APIRouter, BackgroundTasks


from git import Repo

from pydantic import BaseModel

from models.gitModels import Users


class RequestBody(BaseModel):
    uuid: str
    repo_url: str

class CommitHash(BaseModel):
    uuid: str
    repo_url: str
    commit_hash: str


def generate_repo_path(uuid, repo_url):
    repo_name = repo_url.split("/")[-1].replace(".git", "")
    base_path = os.path.join("C:/Users/32965/repo", uuid)
    return os.path.join(base_path, repo_name), repo_name


def get_repo(uuid, repo_url):
    path, _ = generate_repo_path(uuid, repo_url)
    if not os.path.exists(path):
        return 0
    return Repo(path)


gitrouter = APIRouter()


@gitrouter.post("/clone")
async def clone(request: RequestBody, background_tasks: BackgroundTasks):
    local_path, repo_name = generate_repo_path(request.uuid, request.repo_url)
    if os.path.exists(local_path):
        return {"status": "400", "msg": "仓库已存在", "uuid": request.uuid, "repo_url": request.repo_url,
                "path": local_path}
    else:
        background_tasks.add_task(Repo.clone_from, request.repo_url, local_path)
        response = {"status": "200", "msg": "成功创建克隆任务", "uuid": request.uuid, "repo_name": repo_name,
                    "local_path": local_path}
        return response


@gitrouter.post("/log")
async def log(request: RequestBody):
    user=await Users.get(uuid=request.uuid)
    email = user.email
    # email = "gshn666@qq.com"
    email_md5 = hashlib.md5(email.encode(encoding='UTF-8')).hexdigest()
    avatar = "https://cravatar.cn/avatar/"+email_md5+"?d=identicon"
    local_path, _ = generate_repo_path(request.uuid, request.repo_url)
    repo = get_repo(request.uuid, request.repo_url)
    if not repo:
        return {"status": "404", "msg": "仓库不存在", "uuid": request.uuid, "repo_url": request.repo_url,
                "local_path": local_path,"email":email,"avatar":avatar}

    log_ = repo.git.log('--pretty={"commit":"%h","author":"%an","summary":"%s","date":"%cd"}', max_count=50,
                        date='format:%Y-%m-%d %H:%M').split("\n")
    log = list(map(json.loads, log_))
    response = {"status": "200", "msg": "成功获取日志", "uuid": request.uuid, "repo_url": request.repo_url,
                "local_path": local_path, "git_log": log,"email":email,"avatar":avatar}
    return response


@gitrouter.post("/status")
async def status(request: RequestBody):
    repo = get_repo(request.uuid, request.repo_url)
    # 手动获取所有数据
    active_branch = repo.active_branch
    tracking_branch = active_branch.tracking_branch()
    ahead = sum(1 for _ in repo.iter_commits(f"{active_branch}..{tracking_branch}"))
    behind = sum(1 for _ in repo.iter_commits(f"{tracking_branch}..{active_branch}"))
    conflicts = repo.index.unmerged_blobs()
    conflicted = [path for path, entries in conflicts.items()]
    created_files = repo.untracked_files
    current = repo.active_branch.name
    head_commit = repo.head.commit
    tree = head_commit.tree
    all_files = [item.path for item in tree.traverse() if item.type == 'blob']
    diffs = repo.index.diff(None)
    deleted = [d.a_path for d in diffs if d.change_type == 'D']
    detached = repo.head.is_detached
    ignored_files = repo.git.execute(["git", "ls-files", "--others", "--ignored", "--exclude-standard"]).split("\n")
    modified_files = [d.a_path for d in diffs]
    untracked_files = repo.untracked_files
    staged_entries = repo.index.entries
    staged = [path[0] for path, _ in staged_entries.items()]
    tracking = active_branch.tracking_branch().name

    status = {"ahead": ahead, "behind": behind, "conflicted": conflicted, "created": created_files,
              "current": current, "deleted": deleted, "detached": detached, "files": all_files,
              "ignored": ignored_files,
              "modified": modified_files, "not_added": untracked_files, "staged": staged, "tracking": tracking}
    return status
@gitrouter.post("/change")
async def change(request: CommitHash):
    repo = get_repo(request.uuid, request.repo_url)
    if not repo:
        return {"status": "404", "msg": "仓库不存在", "uuid": request.uuid, "repo_url": request.repo_url}
    commit = repo.commit(request.commit_hash)

    if not commit.parents:  # 处理首次提交
        print("首次提交，无父提交对比")
        return

    parent = commit.parents[0]

    diffs = parent.diff(commit,create_patch=True, no_renames=True)

    for diff in diffs:
        print(f"文件 {diff.a_path} ({diff.change_type})：")
        print(diff.diff.decode('utf-8'))


