#!/usr/bin/env python3
import os
import re
import sys
import requests
import subprocess
import zipfile

# Global configuration
API_ENDPOINT = 'https://api.curseforge.com'
API_KEY = '$2a$10$JImTmfu6axMXbi7vPRNZWesM86H83rda4Cs1D7MElzm24XaXBSqYK'  # Set your API key here
MOD_ID = '255109'

# What packwiz file we want, defaults to latest/nightly
PACKWIZ_URI = 'https://nightly.link/packwiz/packwiz/workflows/go/main/Linux%2064-bit%20x86.zip'

PACKWIZ_EXE = "./packwiz"
PACK_FILE = "pack.toml"
UPDATE_INFO = "updateinfo"

HEADERS = {
    'Accept': 'application/json',
    'x-api-key': API_KEY
}


def get_current_version():
    """Request the current version from the API and download it."""
    get_files = f"/v1/mods/{MOD_ID}/files?pageSize=1"
    uri = f"{API_ENDPOINT}{get_files}"
    try:
        response = requests.get(uri, headers=HEADERS)
        response.raise_for_status()
    except Exception as e:
        print("Error while requesting current version:", e)
        sys.exit(1)

    data = response.json().get('data')
    if not data:
        print("No data received from API")
        sys.exit(1)

    # Assuming the API returns one file's info as a dict:
    file_info = data[0]
    download_url = file_info.get("downloadUrl")
    file_name = file_info.get("fileName")
    if not download_url or not file_name:
        print("Missing downloadUrl or fileName in response")
        sys.exit(1)

    # Download the file
    try:
        r = requests.get(download_url, stream=True)
        r.raise_for_status()
        with open(file_name, 'wb') as f:
            for chunk in r.iter_content(chunk_size=8192):
                f.write(chunk)
    except Exception as e:
        print("Error downloading file:", e)
        sys.exit(1)

    print("Current Version File downloaded:", file_name)
    return file_name


def send_version(new_ver):
    """Call the uploader script with the new version."""
    # Construct file name (adjust as needed for your pack naming scheme)
    file_name = f"PiTek 3.0-{new_ver}.zip"
    display_name = os.path.splitext(os.path.basename(file_name))[0]
    if os.path.exists(file_name):
        try:
            # Call the Uploader.py script with arguments.
            subprocess.run(
                ["python3", "Uploader.py", "-f", file_name, "-d", display_name, "-c", UPDATE_INFO],
                check=True
            )
            print("Pack maybe uploaded...")
        except subprocess.CalledProcessError as e:
            print("Error during upload:", e)
            sys.exit(1)
    else:
        print("No file found at", file_name)
        sys.exit(1)


def update_version():
    """Update the version in the pack.toml file and create changelog."""
    try:
        with open(PACK_FILE, 'r') as f:
            content = f.read()
    except Exception as e:
        print("Error reading pack file:", e)
        sys.exit(1)

    # Find current version using regex: version = "..."
    pattern = r'version\s*=\s*"([^"]+)"'
    match = re.search(pattern, content)
    if not match:
        print("Version not found in pack file")
        sys.exit(1)

    try:
        current_version = float(match.group(1))
    except ValueError:
        print("Current version is not a valid number")
        sys.exit(1)

    new_ver = round(current_version + 0.01, 3)
    new_content = re.sub(pattern, f'version = "{new_ver}"', content)
    try:
        with open(PACK_FILE, 'w') as f:
            f.write(new_content)
    except Exception as e:
        print("Error writing updated pack file:", e)
        sys.exit(1)

    print(f"Updated version from {current_version} to {new_ver}")
    new_changelog(new_ver)


def request_update():
    """Run packwiz update, then check the update info and update version if needed."""
    # Clear previous update output
    try:
        with open(UPDATE_INFO, 'w') as f:
            f.write("")
    except Exception as e:
        print("Error clearing update info file:", e)
        sys.exit(1)

    # Run packwiz update command
    try:
        with open(UPDATE_INFO, 'w') as outfile:
            subprocess.run(
                [PACKWIZ_EXE, "update", "--all", "--yes", "--pack-file", PACK_FILE],
                stdout=outfile,
                stderr=subprocess.STDOUT,
                check=True
            )
    except subprocess.CalledProcessError as e:
        print("Error during packwiz update:", e)
        sys.exit(1)

    # Read the update info file
    try:
        with open(UPDATE_INFO, 'r') as f:
            result = f.read()
    except Exception as e:
        print("Error reading update info file:", e)
        sys.exit(1)

    if "All files are up to date!" in result:
        print("No mods to update, exiting")
        sys.exit(0)
    elif "Files updated" in result and "Updates found" in result:
        print("Mods were updated; proceeding")
        update_version()
    else:
        print("Unexpected update result:")
        print(result)


def get_packwiz(uri):
    """Download packwiz, extract it, and set it as executable."""
    zip_filename = "packwiz.zip"
    try:
        r = requests.get(uri, stream=True)
        r.raise_for_status()
        with open(zip_filename, 'wb') as f:
            for chunk in r.iter_content(chunk_size=8192):
                f.write(chunk)
    except Exception as e:
        print("Error fetching Packwiz:", e)
        sys.exit(1)

    # Extract the archive
    try:
        with zipfile.ZipFile(zip_filename, 'r') as zip_ref:
            zip_ref.extractall(os.getcwd())
    except Exception as e:
        print("Error extracting Packwiz archive:", e)
        sys.exit(1)

    # Make packwiz executable
    try:
        subprocess.run(["chmod", "+x", PACKWIZ_EXE], check=True)
    except subprocess.CalledProcessError as e:
        print("Error setting executable permission for packwiz:", e)
        sys.exit(1)


def import_current_pack(current_ver):
    """Import the current pack using packwiz then request an update."""
    try:
        subprocess.run(
            [PACKWIZ_EXE, "curseforge", "import", current_ver, "-y"],
            check=True
        )
    except subprocess.CalledProcessError as e:
        print("Error during pack import:", e)
        sys.exit(1)

    request_update()


def export_new_pack(new_ver):
    """Export the new pack using packwiz and send the version update."""
    try:
        subprocess.run(
            [PACKWIZ_EXE, "curseforge", "export"],
            check=True
        )
    except subprocess.CalledProcessError as e:
        print("Error during pack export:", e)
        sys.exit(1)

    send_version(new_ver)


def new_changelog(new_ver):
    """Create new changelog files from the update info and export new pack."""
    # Read updated mods from updateinfo file.
    try:
        with open(UPDATE_INFO, 'r') as f:
            lines = f.readlines()
    except Exception as e:
        print("Error reading update info for changelog:", e)
        sys.exit(1)

    # Skip first 4 and last 2 lines and remove '.jar'
    updated_mods = [line.replace('.jar', '').strip() for line in lines[4:-2] if line.strip()]

    # Create HTML changelog
    html_file = f"{UPDATE_INFO}.html"
    md_file = f"{UPDATE_INFO}.md"
    try:
        with open(html_file, 'w') as f:
            f.write("Updated Mods\n\n<hr />\n\n\n<ul>\n")
            for mod in updated_mods:
                f.write(f"<li>{mod}</li>\n")
            f.write("</ul>")
        with open(md_file, 'w') as f:
            f.write("**Updated Mods**\n")
            f.write("```md\n")
            for idx, mod in enumerate(updated_mods, start=1):
                f.write(f"{idx}. {mod}\n")
            f.write("```")
    except Exception as e:
        print("Error writing changelog files:", e)
        sys.exit(1)

    # Optionally print out the changelog files
    try:
        with open(html_file, 'r') as f:
            print("HTML Changelog:")
            print(f.read())
        with open(md_file, 'r') as f:
            print("Markdown Changelog:")
            print(f.read())
    except Exception as e:
        print("Error printing changelog files:", e)

    export_new_pack(new_ver)


def main():
    current_version = get_current_version()
    get_packwiz(PACKWIZ_URI)
    import_current_pack(current_version)


if __name__ == '__main__':
    main()
