# -*- coding: utf-8 -*-

# Copyright(C) 2009-2016  Romain Bignon
#
# This file is part of a weboob module.
#
# This weboob module is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This weboob module is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see <http://www.gnu.org/licenses/>.

# yapf-compatible

from __future__ import unicode_literals

from datetime import datetime
from dateutil.relativedelta import relativedelta
import time
from requests.exceptions import ConnectionError, SSLError

from weboob.browser.browsers import LoginBrowser, URL, need_login, StatesMixin
from weboob.capabilities.base import find_object
from weboob.capabilities.bank import (
    AccountNotFound, Account, AddRecipientStep, AddRecipientTimeout,
    TransferInvalidRecipient, Loan,
)
from weboob.capabilities.bill import Subscription, Document, DocumentTypes
from weboob.capabilities.profile import ProfileMissing
from weboob.tools.decorators import retry
from weboob.tools.capabilities.bank.transactions import sorted_transactions
from weboob.browser.exceptions import ServerError
from weboob.browser.elements import DataError
from weboob.exceptions import BrowserIncorrectPassword, BrowserUnavailable
from weboob.tools.value import Value, ValueBool
from weboob.tools.capabilities.bank.investments import create_french_liquidity

from .pages import (
    LoginPage, AccountsPage, AccountsIBANPage, HistoryPage, TransferInitPage,
    ConnectionThresholdPage, LifeInsurancesPage, LifeInsurancesHistoryPage,
    LifeInsurancesDetailPage, NatioVieProPage, CapitalisationPage,
    MarketListPage, MarketPage, MarketHistoryPage, MarketSynPage, BNPKeyboard,
    RecipientsPage, ValidateTransferPage, RegisterTransferPage, AdvisorPage,
    AddRecipPage, ActivateRecipPage, ProfilePage, ListDetailCardPage, ListErrorPage,
    UselessPage, TransferAssertionError, LoanDetailsPage,
)

from .document_pages import DocumentsPage, DocumentsResearchPage, TitulairePage, RIBPage

__all__ = ['BNPPartPro', 'HelloBank']


class BNPParibasBrowser(LoginBrowser, StatesMixin):
    TIMEOUT = 30.0

    login = URL(
        r'identification-wspl-pres/identification\?acceptRedirection=true&timestamp=(?P<timestamp>\d+)',
        r'SEEA-pa01/devServer/seeaserver',
        r'https://mabanqueprivee.bnpparibas.net/fr/espace-prive/comptes-et-contrats\?u=%2FSEEA-pa01%2FdevServer%2Fseeaserver',
        LoginPage
    )

    list_error_page = URL(
        r'https://mabanque.bnpparibas/rsc/contrib/document/properties/identification-fr-part-V1.json', ListErrorPage
    )

    useless_page = URL(r'/fr/connexion/comptes-et-contrats', UselessPage)

    con_threshold = URL(
        r'/fr/connexion/100-connexions',
        r'/fr/connexion/mot-de-passe-expire',
        r'/fr/espace-prive/100-connexions.*',
        r'/fr/espace-pro/100-connexions-pro.*',
        r'/fr/espace-pro/changer-son-mot-de-passe',
        r'/fr/espace-client/100-connexions',
        r'/fr/espace-prive/mot-de-passe-expire',
        r'/fr/client/mdp-expire',
        r'/fr/client/100-connexion',
        r'/fr/systeme/page-indisponible',
        ConnectionThresholdPage
    )
    accounts = URL(r'udc-wspl/rest/getlstcpt', AccountsPage)
    loan_details = URL(r'caraccomptes-wspl/rpc/(?P<loan_type>.*)', LoanDetailsPage)
    ibans = URL(r'rib-wspl/rpc/comptes', AccountsIBANPage)
    history = URL(r'rop2-wspl/rest/releveOp', HistoryPage)
    history_old = URL(r'rop-wspl/rest/releveOp', HistoryPage)
    transfer_init = URL(r'virement-wspl/rest/initialisationVirement', TransferInitPage)

    lifeinsurances = URL(r'mefav-wspl/rest/infosContrat', LifeInsurancesPage)
    lifeinsurances_history = URL(r'mefav-wspl/rest/listMouvements', LifeInsurancesHistoryPage)
    lifeinsurances_detail = URL(r'mefav-wspl/rest/detailMouvement', LifeInsurancesDetailPage)

    natio_vie_pro = URL(r'/mefav-wspl/rest/natioViePro', NatioVieProPage)
    capitalisation_page = URL(
        r'https://www.clients.assurance-vie.fr/servlets/helios.cinrj.htmlnav.runtime.FrontServlet', CapitalisationPage
    )

    market_list = URL(r'pe-war/rpc/SAVaccountDetails/get', MarketListPage)
    market_syn = URL(r'pe-war/rpc/synthesis/get', MarketSynPage)
    market = URL(r'pe-war/rpc/portfolioDetails/get', MarketPage)
    market_history = URL(r'/pe-war/rpc/turnOverHistory/get', MarketHistoryPage)

    recipients = URL(r'/virement-wspl/rest/listerBeneficiaire', RecipientsPage)
    add_recip = URL(r'/virement-wspl/rest/ajouterBeneficiaire', AddRecipPage)
    activate_recip_sms = URL(r'/virement-wspl/rest/activerBeneficiaire', ActivateRecipPage)
    activate_recip_digital_key = URL(r'/virement-wspl/rest/verifierAuthentForte', ActivateRecipPage)
    validate_transfer = URL(r'/virement-wspl/rest/validationVirement', ValidateTransferPage)
    register_transfer = URL(r'/virement-wspl/rest/enregistrerVirement', RegisterTransferPage)

    advisor = URL(r'/conseiller-wspl/rest/monConseiller', AdvisorPage)

    titulaire = URL(r'/demat-wspl/rest/listerTitulairesDemat', TitulairePage)
    document = URL(r'/demat-wspl/rest/listerDocuments', DocumentsPage)
    document_research = URL(r'/demat-wspl/rest/rechercheCriteresDemat', DocumentsResearchPage)
    rib_page = URL(r'/rib-wspl/rpc/restituerRIB', RIBPage)

    profile = URL(r'/kyc-wspl/rest/informationsClient', ProfilePage)
    list_detail_card = URL(r'/udcarte-wspl/rest/listeDetailCartes', ListDetailCardPage)

    STATE_DURATION = 10

    need_reload_state = False

    __states__ = ('need_reload_state', 'rcpt_transfer_id')

    def __init__(self, config, *args, **kwargs):
        super(BNPParibasBrowser, self).__init__(config['login'].get(), config['password'].get(), *args, **kwargs)
        self.accounts_list = None
        self.card_to_transaction_type = {}
        self.rotating_password = config['rotating_password'].get()
        self.digital_key = config['digital_key'].get()
        self.rcpt_transfer_id = None

    @retry(ConnectionError, tries=3)
    def open(self, *args, **kwargs):
        return super(BNPParibasBrowser, self).open(*args, **kwargs)

    def do_login(self):
        if not (self.username.isdigit() and self.password.isdigit()):
            raise BrowserIncorrectPassword()
        timestamp = lambda: int(time.time() * 1e3)
        self.login.go(timestam
p=timestamp())
        if self.login.is_here():
            self.page.login(self.username, self.password)

    def load_state(self, state):
        # reload state only for new recipient feature
        if state.get('need_reload_state'):
            sta
te.pop('url', None)
            self.need_reload_state = False
            super(BNPParibasBrowser, self).load_state(state)

    def change_pass(self, oldpass, newpass):
        res = self.open('/identification-wspl-pres/grille?accessible=false')
        url = '/identification-wspl-pres/grille/%s' % res.json()['data']['idGrille']
        keyboard = self.open(url)
        vk = BNPKeyboard(self, keyboard)
        data = {}
        data['codeAppli'] = 'PORTAIL'
        data['idGrille'] = res.json()['data']['idGrille']
        data['typeGrille'] = res.json()['data']['typeGrille']
        data['confirmNouveauPassword'] = vk.get_string_code(newpass)
        data['nouveauPassword'] = vk.get_string_code(newpass)
        data['passwordActuel'] = vk.get_string_code(oldpass)
        response = self.location('/mcs-wspl/rpc/modifiercodesecret', data=data)
        if response.json().get('messageIden').lower() == 'nouveau mot de passe invalide':
            return False
        return True

    @need_login
    def get_profile(self):
        self.profile.go(json={}, method='POST')
        profile = self.page.get_profile()
        if profile:
            return profile
  