import datetime
import random
import re
import time

import pyotp
import pytz
from selenium.webdriver.common.keys import Keys

from sbc.login_to_ea_with_selenium import get_webdriver_with_proxy, wait_for_element, get_webdriver_without_proxy
from sbc.public_methods import get_last_email, new_print
from sbc.sbc_solver import SBCSolver


class LinkAccountBot(SBCSolver):

    def link_account(self, support_email='', support_password='',
                     support_imap_host='outlook.office365.com', gamer_tag='',
                     just_check_suspend=False):
        self.fifa_account.refresh_from_db()
        fifa_backup = self.fifa_account.account_backup_code.first()
        app_code = fifa_backup.app_code
        # print('getting proxy. if proxy not set before and bot not in server it make so long time.')
        # proxy_ip, proxy_port, proxy_user, proxy_pass, proxy_id = self.set_sbc_proxy()
        new_print(self.fifa_account, 'linking account bot started')
        print('getting webdriver')
        # web_driver = get_webdriver_with_proxy(self.fifa_account.user_name, proxy_ip, proxy_port, proxy_user, proxy_pass)
        web_driver = get_webdriver_without_proxy(self.fifa_account.user_name)
        print('login to xbox page')
        web_driver.get('https://www.xbox.com/en-us/')
        time.sleep(5)
        web_driver.find_element_by_id('meControl').click()
        time.sleep(5)
        print('enter user name : ', self.fifa_account.user_name)
        email_input = web_driver.find_element_by_name('loginfmt')
        for char in str(self.fifa_account.user_name):
            email_input.send_keys(char)
            time.sleep(.2)
        web_driver.find_element_by_id('idSIButton9').click()
        time.sleep(5)
        password_input = web_driver.find_element_by_name('passwd')
        for char in str(self.fifa_account.xbox_pass):
            password_input.send_keys(char)
            time.sleep(.2)
        print('enter password : ', self.fifa_account.xbox_pass)
        web_driver.find_element_by_id('idSIButton9').click()
        time.sleep(10)
        try:
            web_driver.find_element_by_xpath("//div[text()='For your security and to ensure only you have access to your account, we will ask you to verify your identity and change your password.']")
            raise Exception('need phone number')
        except:
            print('can not find need phone')
        try:
            web_driver.find_element_by_xpath("//div[text()='Your account has been locked']")
            raise Exception('account has been locked')
        except:
            print('can not find account locked')
        local_tz = pytz.timezone('Asia/Tehran')
        for tt in range(2):
            need_support = wait_for_element(
                'xpath', 'one', "//div[text()='Help us protect your account']", driver=web_driver)
            if need_support:
                print('need support')
                if support_email:
                    start_time = datetime.datetime.now(local_tz)
                    time.sleep(5)
                    try:
                        web_driver.find_element_by_xpath('//input[@name="proof"]').click()
                        print('support email need proof')
                        time.sleep(2)
                        support_email_input = web_driver.find_element_by_name('iProofEmail')
                        for char in str(support_email):
                            support_email_input.send_keys(char)
                            time.sleep(.2)
                        web_driver.find_element_by_id('iSelectProofAction').click()
                        time.sleep(2)
                        print('this email already proofed')
                    except Exception as error:
                        print('find proof error : ', error)
                        support_email_input = web_driver.find_element_by_name('EmailAddress')
                        for char in str(support_email):
                            support_email_input.send_keys(char)
                            time.sleep(.2)
                        web_driver.find_element_by_id('iNext').click()
                    security_code = None
                    for wait_time in range(20):
                        last_email = get_last_email(
                            imap_user=support_email, imap_pass=support_password, imap_host=support_imap_host
                        )
                        if last_email.get('body', None) and last_email.get('time') > start_time:
                            # get security code
                            search_security_code = re.search(r'Security code: (\d+)', last_email.get('body'))
                            if search_security_code:
                                security_code = search_security_code.group(1)
                                break
                        else:
                            print('last email : ', last_email.get('time'), ' start time : ', start_time)
                            time.sleep(10)
                            continue
                    if security_code is None:
                        raise Exception('can not get security code')
                    time.sleep(2)
                    wait_for_element('xpath', 'one', '//div[@id="iEnterSubhead"]', driver=web_driver)
                    support_password_input = web_driver.find_element_by_id('iOttText')
                    print('security code  = ', security_code)
                    for char in str(security_code):
                        support_password_input.send_keys(char)
                        time.sleep(.2)
                    try:
                        web_driver.find_element_by_id('iVerifyCodeAction').click()
                    except:
                        web_driver.find_element_by_id('iNext').click()
                    print('security code entered')
                    time.sleep(5)
                else:
                    raise Exception('need support email')
            else:
                break

        # don't  stay signed in

        if wait_for_element('xpath', 'one', '//*[@id="idBtn_Back"]', driver=web_driver):
            time.sleep(2)
            print('stay signed out')
            web_driver.find_element_by_xpath('//*[@id="idBtn_Back"]').click()
            time.sleep(5)
        if wait_for_element('xpath', 'one', '//*[@id="iCancel"]', driver=web_driver):
            time.sleep(2)
            # break from your password
            print('break form your password')
            web_driver.find_element_by_xpath('//*[@id="iCancel"]').click()
            time.sleep(5)
        # share my data with other platforms
        share_data_elem = wait_for_element('xpath', 'one', '//*[@id="partnerMarketing"]', driver=web_driver)
        if share_data_elem:
            print('share data with other platforms')
            time.sleep(2)
            web_driver.find_element_by_xpath('//*[*[@id="partnerMarketing"]]').click()
            time.sleep(1)
            web_driver.find_element_by_xpath('//*[@id="Accept"]').click()
        # account suspend error
        account_suspend = wait_for_element(
            'xpath', 'one',
            '//*[text()="We can\'t sign you in because your account has been suspended from Xbox Live."]',
            driver=web_driver)
        if account_suspend:
            print('account suspend')
            raise Exception('account suspend')
        if just_check_suspend:
            web_driver.close()
            return
        time.sleep(15)
        if gamer_tag:
            print('start change gamer tag, new : ', gamer_tag)
            time.sleep(10)
            if not web_driver.current_url.startswith('https://sisu.xboxlive.com/'):
                web_driver.get('https://social.xbox.com/changegamertag')
            time.sleep(5)
            # try:
            #     web_driver.find_element_by_id('create-account-gamertag-suggestion-1').click()
            #     time.sleep(2)
            #     web_driver.find_element_by_id('inline-continue-control').click()
            #     time.sleep(5)
            #     wait_for_element('xpath', 'one', '//*[@id="ChooseScreenGamertagInput"]', driver=web_driver)
            #     time.sleep(5)
            # except:
            #     print('first page gamer tag was ok')
            try:
                # check_gamer_tag_input = web_driver.find_element_by_id('ChooseScreenGamertagInput')
                check_gamer_tag_input = web_driver.find_element_by_id('create-account-gamertag-input')
            except:
                try:
                    web_driver.find_element_by_xpath(
                        "//div[text()='For your security and to ensure only you have access to your account, we will ask you to verify your identity and change your password.']")
                    raise Exception('need phone number')
                except:
                    print('can not find need phone')
                try:
                    web_driver.find_element_by_xpath("//div[text()='Your account has been locked']")
                    raise Exception('account has been locked')
                except:
                    print('can not find account locked')
                raise Exception('can not find gamer tag input')
            time.sleep(2)
            need_enter_gamer_tage = True
            for ssss in range(10):
                if need_enter_gamer_tage:
                    for nm in str(gamer_tag) + ' ' + str(random.randint(300000, 1000000)):
                        check_gamer_tag_input.send_keys(nm)
                        time.sleep(.2)
                    need_enter_gamer_tage = False
                time.sleep(5)
                try:
                    web_driver.find_element_by_xpath(
                        "//input[@id='create-account-gamertag-input' and @class='success']")
                    print('gamer tag success')
                    break
                except:
                    print('gamer tag not success')
                try:
                    web_driver.find_element_by_xpath(
                        "//input[@id='create-account-gamertag-input' and @class='failure']")
                    for sss in range(20):
                        web_driver.send_keys(Keys.BACKSPACE)
                    need_enter_gamer_tage = True
                    print('gamer tag failure , try again')
                except:
                    pass
            web_driver.find_element_by_id('inline-continue-control').click()
            time.sleep(5)
            print('confirm gamer tag')

            # confirm_gamer_tag = wait_for_element(
            #     'xpath', 'one', '//*[@id="ConfirmScreenClaimDoneButton"]', driver=web_driver
            # )
            # if not confirm_gamer_tag:
            #     gamer_tag_already_exists = wait_for_element(
            #         'xpath', 'one',
            #         '//p[text()="You already own that gamertag, if you’re happy with it you don’t need to make any changes."]',
            #         driver=web_driver)
            #     if gamer_tag_already_exists:
            #         print('gamer tage already exists : ', gamer_tag)
            #     else:
            #         print('something error on enter gamer tag : ', gamer_tag)
            #         time.sleep(60)
            # else:
            #     print('change gamer tag found')
            #     time.sleep(2)
            #     web_driver.find_element_by_id('ConfirmScreenClaimDoneButton').click()
            #     time.sleep(2)
            #     web_driver.find_element_by_xpath(
            #         '//button[text()="Change gamertag" and @class="btn btn btn-secondary"]'
            #     ).click()
            #     if wait_for_element('xpath', 'one', '//span[@class="successtitle"]', driver=web_driver):
            #         print('change gamer tag success')

        # login to ea with xbox account
        time.sleep(10)
        print('login to ea with xbox')
        if not web_driver.current_url.startswith('https://www.ea.com/login'):
            web_driver.get('https://www.ea.com/login')
        time.sleep(2)
        for i in range(5):
            if web_driver.current_url == 'https://www.ea.com/login':
                web_driver.refresh()
                time.sleep(5)
            else:
                break
        web_driver.find_element_by_xpath('//span[@class="xbox-icon"]').click()
        time.sleep(5)
        if len(web_driver.window_handles) > 1:
            print('open xbox page in new window')
            old_window = web_driver.window_handles[0]
            new_window = web_driver.window_handles[1]
            web_driver.switch_to_window(new_window)
            wait_for_element('xpath', 'one', '//*[@id="idBtn_Accept"]', driver=web_driver)
            time.sleep(2)
            web_driver.find_element_by_id('idBtn_Accept').click()
            time.sleep(2)
            web_driver.switch_to_window(old_window)
        print('switch back to old window')
        continue_button = wait_for_element('xpath', 'one', '//*[@id="continue"]', driver=web_driver)
        if continue_button:
            time.sleep(2)
            web_driver.find_element_by_id('continue').click()
            wait_for_element('xpath', 'one', '//*[@id="APP"]', driver=web_driver)
            time.sleep(2)
            web_driver.find_element_by_id('APPLabel').click()
            time.sleep(1)
            print('send code for app code')
            web_driver.find_element_by_id('btnSendCode').click()
            wait_for_element('xpath', 'one', '//*[@id="twoFactorCode"]', driver=web_driver)
            time.sleep(5)
            two_factor_input = web_driver.find_element_by_id('twoFactorCode')
            print('app code : ', app_code)
            totp = pyotp.TOTP(app_code)
            backup_code = totp.now()
            print('totp code : ', backup_code)
            for nt_char in str(backup_code):
                two_factor_input.send_keys(nt_char)
                time.sleep(.2)
            time.sleep(1)
            web_driver.find_element_by_id('btnSubmit').click()
            wait_for_element('xpath', 'one', '//*[@id="continue"]', driver=web_driver)
            time.sleep(2)
            web_driver.find_element_by_id('continue').click()
            wait_for_element('xpath', 'one', '//*[@id="continueBtn"]', driver=web_driver)
            time.sleep(2)
            web_driver.find_element_by_id('continueBtn').click()
        else:
            print('something error in login to ea : ', self.fifa_account.user_name)
            time.sleep(60)
        web_driver.close()
        print('all process complete')
