import requests
import json
import os
import subprocess
import sys
from datetime import datetime
from dotenv import load_dotenv

load_dotenv()

lang_list = ['en','zh-TW','ja', 'ko', 'fr', 'de', 'es', 'it', 'nl', 'pl', 'pt', 'ru', 'tr', 'vi', 'zh-CN']

def run_git_command(command):
    try:
        result = subprocess.run(command, shell=True, capture_output=True, text=True, cwd="/app")
        if result.returncode != 0:
            print(f"Git command failed: {command}")
            print(f"Error: {result.stderr}")
            return False
        return True
    except Exception as e:
        print(f"Error running git command: {e}")
        return False

def clean_untracked_files():
    print("Cleaning up untracked files that might cause conflicts...")
    
    try:
        status_result = subprocess.run("git status --porcelain", shell=True, capture_output=True, text=True, cwd="/app")
        if status_result.stdout.strip():
            untracked_files = []
            for line in status_result.stdout.strip().split('\n'):
                if line.startswith('??'):
                    untracked_files.append(line[3:])
            
            if untracked_files:
                print(f"Found {len(untracked_files)} untracked files, removing them...")
                for file_path in untracked_files:
                    if os.path.exists(file_path):
                        os.remove(file_path)
                        print(f"Removed: {file_path}")
        
        return True
    except Exception as e:
        print(f"Error cleaning untracked files: {e}")
        return False

def setup_git_repo():
    git_repo_url = os.environ.get('GIT_REPO_URL')
    git_username = os.environ.get('GIT_USERNAME')
    git_email = os.environ.get('GIT_EMAIL')
    git_branch = os.environ.get('GIT_BRANCH', 'main')
    github_token = os.environ.get('GITHUB_TOKEN')
    
    if not all([git_repo_url, git_username, git_email]):
        print("Git environment variables not set. Skipping Git operations.")
        return False
    
    if not os.path.exists("/app/.git"):
        print("Initializing Git repository...")
        if not run_git_command("git init"):
            return False
        
        if github_token and git_repo_url.startswith('https://'):
            print("Using GitHub Personal Access Token for authentication...")
            auth_url = git_repo_url.replace('https://', f'https://{git_username}:{github_token}@')
            if not run_git_command(f"git remote add origin {auth_url}"):
                return False
        else:
            if not run_git_command(f"git remote add origin {git_repo_url}"):
                return False
        
        if not run_git_command(f"git checkout -b {git_branch}"):
            return False
        
        print("Checking if remote repository has content...")
        fetch_result = subprocess.run("git fetch origin", shell=True, capture_output=True, text=True, cwd="/app")
        if fetch_result.returncode == 0:
            print("Remote repository found, checking for conflicts...")
            ls_remote = subprocess.run("git ls-remote --heads origin main", shell=True, capture_output=True, text=True, cwd="/app")
            if ls_remote.stdout.strip():
                print("Remote main branch exists, resetting to remote state...")
                clean_untracked_files()
                run_git_command("git fetch origin")
                run_git_command("git reset --hard origin/main")
            else:
                print("Remote main branch doesn't exist, creating initial commit...")
                run_git_command("git add .")
                run_git_command("git commit -m 'Initial commit'")
        else:
            print("Could not fetch from remote, creating initial commit...")
            run_git_command("git add .")
            run_git_command("git commit -m 'Initial commit'")
    else:
        if github_token and git_repo_url.startswith('https://'):
            print("Updating remote URL with authentication...")
            auth_url = git_repo_url.replace('https://', f'https://{git_username}:{github_token}@')
            if not run_git_command(f"git remote set-url origin {auth_url}"):
                return False
        
        print("Repository already exists, fetching latest changes...")
        if not run_git_command("git fetch origin"):
            print("Warning: Could not fetch from remote")
        else:
            print("Checking if we need to reset to remote state...")
            local_commit = subprocess.run("git rev-parse HEAD", shell=True, capture_output=True, text=True, cwd="/app")
            remote_commit = subprocess.run("git rev-parse origin/main", shell=True, capture_output=True, text=True, cwd="/app")
            
            if local_commit.returncode == 0 and remote_commit.returncode == 0:
                if local_commit.stdout.strip() != remote_commit.stdout.strip():
                    print("Local and remote are different, resetting to remote state...")
                    clean_untracked_files()
                    run_git_command("git reset --hard origin/main")
    
    run_git_command(f"git config user.name '{git_username}'")
    run_git_command(f"git config user.email '{git_email}'")
    
    if github_token:
        run_git_command("git config credential.helper store")
    
    return True

def verify_git_remote():
    result = subprocess.run("git remote -v", shell=True, capture_output=True, text=True, cwd="/app")
    if result.returncode != 0:
        print("Error checking Git remote configuration")
        return False
    
    remote_output = result.stdout.strip()
    if not remote_output:
        print("No Git remote configured")
        return False
    
    print(f"Git remote configuration: {remote_output}")
    return True

def handle_git_conflicts():
    print("Handling potential Git conflicts...")
    
    try:
        print("Fetching latest changes from remote...")
        if not run_git_command("git fetch origin"):
            print("Warning: Could not fetch from remote")
            return False
        
        print("Resetting to remote state to resolve conflicts...")
        if not run_git_command("git reset --hard origin/main"):
            print("Warning: Could not reset to remote state")
            return False
        
        print("Re-applying language file changes...")
        return True
    except Exception as e:
        print(f"Error handling Git conflicts: {e}")
        return False

def commit_and_push_changes():
    if not os.path.exists("/app/.git"):
        return False
    
    if not verify_git_remote():
        print("Git remote not properly configured")
        return False
    
    try:
        run_git_command("git add .")
        run_git_command("git commit -m 'Update language files'")
        
        github_token = os.environ.get('GITHUB_TOKEN')
        if github_token:
            git_repo_url = os.environ.get('GIT_REPO_URL')
            git_username = os.environ.get('GIT_USERNAME')
            if git_repo_url.startswith('https://'):
                auth_url = git_repo_url.replace('https://', f'https://{git_username}:{github_token}@')
                print(f"Setting authenticated remote URL: {auth_url}")
                run_git_command(f"git remote set-url origin {auth_url}")
                
                print("Updated Git remote configuration:")
                run_git_command("git remote -v")
        
        print("Attempting to push changes...")
        push_result = subprocess.run("git push origin HEAD", shell=True, capture_output=True, text=True, cwd="/app")
        
        if push_result.returncode == 0:
            print("Changes committed and pushed to Git repository")
            return True
        else:
            print(f"Push failed: {push_result.stderr}")
            
            if "rejected" in push_result.stderr and "fetch first" in push_result.stderr:
                print("Remote has changes, attempting to resolve conflicts...")
                if handle_git_conflicts():
                    print("Retrying push after resolving conflicts...")
                    if run_git_command("git push origin HEAD"):
                        print("Changes successfully pushed after resolving conflicts")
                        return True
            
            return False
            
    except Exception as e:
        print(f"Error pushing to Git: {e}")
        return False

def download_and_compare_json(lang):
    #url = f"https://highschool.stg.g123-cpp.com/1/g123/i18n/{lang}/texts/source_schooltest_1.json"
    url = f"https://highschool.stg.g123-cpp.com/G123Test1/g123/i18n/{lang}/texts/source_schooltest_1.json"
    
    try:
        response = requests.get(url)
        response.raise_for_status()
        new_data = response.json()
    except requests.RequestException as e:
        print(f"Error downloading JSON: {e}")
        return
    except json.JSONDecodeError as e:
        print(f"Error parsing JSON: {e}")
        return
    
    old_data = {}
    if os.path.exists(f"{lang}.json"):
        try:
            with open(f"{lang}.json", "r", encoding="utf-8") as f:
                old_data = json.load(f)
        except (json.JSONDecodeError, FileNotFoundError):
            print(f"Warning: Could not read existing {lang}.json, treating as empty")
    
    diff_lines = []
    diff_lines.append(f"--- {lang}.json")
    diff_lines.append(f"+++ {lang}.json")
    diff_lines.append("")
    
    all_keys = sorted(set(old_data.keys()) | set(new_data.keys()))
    
    for key in all_keys:
        if key not in old_data:
            diff_lines.append(f"+{key}: {json.dumps(new_data[key], ensure_ascii=False)}")
        elif key not in new_data:
            diff_lines.append(f"-{key}: {json.dumps(old_data[key], ensure_ascii=False)}")
        elif old_data[key] != new_data[key]:
            diff_lines.append(f"-{key}: {json.dumps(old_data[key], ensure_ascii=False)}")
            diff_lines.append(f"+{key}: {json.dumps(new_data[key], ensure_ascii=False)}")
    
    with open(f"{lang}.json", "w", encoding="utf-8") as f:
        json.dump(new_data, f, indent=2, ensure_ascii=False)
    
    if len(diff_lines) > 3:
        with open(f"{lang}.diff", "w", encoding="utf-8") as f:
            f.write("\n".join(diff_lines))
        print(f"Changes detected: {len(diff_lines) - 3} lines affected")
        print(f"Diff saved to {lang}.diff")
    else:
        print("No changes detected")
    
    print(f"New data saved to {lang}.json ({len(new_data)} keys)")

if __name__ == "__main__":
    git_enabled = setup_git_repo()
    
    for lang in lang_list:
        download_and_compare_json(lang)
    
    if git_enabled:
        commit_and_push_changes()
