import re
from utils import print_title, print_error, print_success, run_sub_process_without_output, run_sub_process, show_menu, read_option
from git_utils import get_staging_and_production_branches, update_branch, get_next_tag, get_current_branch, create_and_push_tag, save_changes
from versioning import bump_branch_version, update_android_version, update_ios_version, update_eas_runtime_version, get_current_version

bitrise_success_message = 'Success, visit https://app.bitrise.io/dashboard to check progress'

def run_option(option, options):
    options[option][1]()

def get_menu(options, optionClose):
    option = None
    while option != optionClose:
        show_menu(options)
        option = read_option(options)
        run_option(option, options)
        print()

def main_menu():
    options = {
        '1': ('Init Release', init_release),
        '2': ('Release Prod', release_prod),
        '3': ('Release Prod Expo', release_prod_expo),
        '4': ('Release Stg', release_stg),
        '5': ('Release Stg Expo', release_stg_expo),
        '6': ('Release Dev', release_dev),
        '7': ('Release Dev Expo', release_dev_expo),
        '8': ('Update App version', update_app_version),
        '9': ('Show Staging and Prod branches', show_current_env_branches),
        '10': ('Exit', close),
    }
    get_menu(options, str(len(options)))

def update_app_version():
    newVersionName = update_android_version()
    print(f'New versionName (Android): {newVersionName}')
    updated_version = update_ios_version(newVersionName)
    print(f'Updated version (iOS): {updated_version}')
    new_runtime_version = update_eas_runtime_version()
    print(f'New runtime version (Expo): {new_runtime_version}')
    print('Installing dependencies')
    run_sub_process_without_output('yarn install')
    save_changes(f'App version {updated_version} ')
    return newVersionName

def init_release():
    print_title('Starting release')
    current_branch = get_current_branch()
    if current_branch == 'develop':
        print('Saving uncommint changes')
        run_sub_process('git stash')
        print('Fetching all')
        run_sub_process_without_output('git fetch --all')
        print('Updating develop branch')
        run_sub_process_without_output('git pull origin develop')
        staging, production = get_staging_and_production_branches()
        print(f'Staging version: {staging}')
        newStagingVersion = bump_branch_version(staging)
        print(f'New staging version: {newStagingVersion}')
        print(f'Creating release branch: {newStagingVersion}')
        run_sub_process(f'git checkout -b tech/bump-version-{newStagingVersion}')
        print('Updating release branch')
        update_app_version()
        print('Creating PR')
        run_sub_process_without_output(f'gh pr create --title "Tech | App version {newStagingVersion}" --body "" --label "Release,Tech,no-review" --base develop --assignee "@me"')

def release_store(env):
    current_branch = get_current_branch()
    if re.match(r'v\d+\.\d+\.\d+', current_branch):
        print_title(f'Release {env.capitalize()}')
        update_branch(current_branch)
        tag_base = f'{current_branch}-{env}'
        nextTag = get_next_tag(tag_base)
        create_and_push_tag(f'{tag_base}-{nextTag}')
        print_success(bitrise_success_message)
    else:
        print_error('Current branch is not a staging or production branch')

def release_expo_updates(env):
    current_branch = get_current_branch()
    if re.match(r'v\d+\.\d+\.\d+', current_branch):
        print_title(f'Release {env.capitalize()} Expo Updates')
        update_branch(current_branch)
        tag_base = f'{current_branch}-{env}-eu'
        nextTag = get_next_tag(tag_base)
        create_and_push_tag(f'{tag_base}-{nextTag}')
        print_success(bitrise_success_message)
    else:
        print_error('Current branch is not a staging or production branch')

def release_prod():
    release_store('prod')

def release_prod_expo():
    release_expo_updates('prod')

def release_stg():
    release_store('stg')

def release_stg_expo():
    release_expo_updates('stg')

def release_dev():
    print_title('Release Dev')
    current_version = get_current_version()
    tag_base = f'v{current_version}-dev'
    nextTag = get_next_tag(tag_base)
    create_and_push_tag(f'{tag_base}-{nextTag}')
    print_success(bitrise_success_message)

def release_dev_expo():
    print_title(f'Release Dev Expo Updates')
    current_version = get_current_version()
    tag_base = f'v{current_version}-dev-eu'
    nextTag = get_next_tag(tag_base)
    create_and_push_tag(f'{tag_base}-{nextTag}')
    print_success(bitrise_success_message)

def show_current_env_branches():
    print_title("Staging and Production branches")
    try:
        staging, production = get_staging_and_production_branches()
        print(f"Staging: \033[0;32m{staging}\033[0;m")
        print(f"Production: \033[0;33m{production}\033[0;m")
    except Exception as e:
        print_error(str(e))

def close():
    print('Closing')

if __name__ == '__main__':
    main_menu()
