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

# Copyright(C) 2014  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/>.

from __future__ import unicode_literals

from weboob.browser.elements import ListElement, ItemElement, method
from .compat.weboob_browser_filters_standard import CleanText, CleanDecimal, Coalesce, Currency, Date, Map, Field, Regexp
from weboob.browser.filters.html import AbsoluteLink, Link
from weboob.browser.pages import LoggedPage, pagination
from .compat.weboob_capabilities_bank import Account
from weboob.capabilities.profile import Company
from weboob.capabilities.base import NotAvailable
from weboob.exceptions import BrowserUnavailable

from .accounthistory import Transaction
from .base import MyHTMLPage


class RedirectPage(LoggedPage, MyHTMLPage):
    def check_for_perso(self):
        return self.doc.xpath('''//p[contains(text(), "L'identifiant utilisé est celui d'un compte de Particuliers")]''')


ACCOUNT_TYPES = {
    'Comptes titres': Account.TYPE_MARKET,
    'Comptes épargne': Account.TYPE_SAVINGS,
    'Comptes courants': Account.TYPE_CHECKING,
}


class ProAccountsList(LoggedPage, MyHTMLPage):

    # TODO Be careful about connections with personnalized account groups
    # According to their presentation video (https://www.labanquepostale.fr/pmo/nouvel-espace-client-business.html),
    # on the new website people are able to make personnalized groups of account instead of the usual drop-down categories on which to parse to find a match in ACCOUNT_TYPES
    # If clients use the functionnality we might need to add entries new in ACCOUNT_TYPES

    def on_load(self):
        if self.doc.xpath('//div[@id="erreur_generale"]'):
            raise BrowserUnavailable(CleanText('//div[@id="erreur_generale"]//p[contains(text(), "Le service est momentanément indisponible")]')(self.doc))

    def is_here(self):
        return CleanText('//h1[contains(text(), "Synthèse des comptes")]')(self.doc)

    @method
    class iter_accounts(ListElement):
        item_xpath = '//div[@id="mainContent"]//div[h3/a]'

        class item(ItemElement):
            klass = Account

            obj_id = Regexp(CleanText('./h3/a/@title'), r'([A-Z\d]{4}[A-Z\d\*]{3}[A-Z\d]{4})')
            obj_balance = CleanDecimal.French('./span/text()[1]')  # This website has the good taste of leaving hard coded HTML comments. This is the way to pin point to the righ text item.
            obj_currency = Currency('./span')
            obj_url = AbsoluteLink('./h3/a')

            # account are grouped in /div based on their type, we must fetch the closest one relative to item_xpath
            obj_type = Map(CleanText('./ancestor::div[1]/preceding-sibling::h2[1]/button/div[@class="title-accordion"]'), ACCOUNT_TYPES, Account.TYPE_UNKNOWN)

            def obj_label(self):
                """ Need to get rid of the id wherever we find it in account labels like "LIV A 0123456789N MR MOMO" (livret A) as well as "0123456789N MR MOMO" (checking account) """
                return CleanText('./h3/a/@title')(self).replace('%s ' % Field('id')(self), '')


class ProAccountHistory(LoggedPage, MyHTMLPage):
    @pagination
    @method
    class iter_history(ListElement):
        item_xpath = '//div[@id="tabReleve"]//tbody/tr'

        def next_page(self):
            # The next page on the website can return pages already visited without logical mechanism
            # Nevertheless we can skip these pages with the comparaison of the first transaction of the page

            next_page_xpath = '//div[@class="pagination"]//li[@class="pagin-on-right"]/a'
            tr_xpath = '//tbody/tr[1]'
            self.page.browser.first_transactions.append(CleanText(tr_xpath)(self.el))
            next_page_link = Link(next_page_xpath)(self.el)
            next_page = self.page.browser.location(next_page_link)
            first_transaction = CleanText(tr_xpath)(next_page.page.doc)
            count = 0  # avoid an infinite loop

            while first_transaction in self.page.browser.first_transactions and count < 30:
                next_page = self.page.browser.location(next_page_link)
                next_page_link = Link(next_page_xpath)(next_page.page.doc)
                first_transaction = CleanText(tr_xpath)(next_page.page.doc)
                count += 1

            if count < 30:
                return next_page.page

        class item(ItemElement):
            klass = Transaction

            obj_date = Date(CleanText('.//td[@headers="date"]'), dayfirst=True)
            obj_raw = Transaction.Raw('.//td[@headers="libelle"]')
            obj_amount = Coalesce(
                CleanDecimal.French('.//td[@headers="debit"]', default=NotAvailable),
                CleanDecimal.French('.//td[@headers="credit"]', default=NotAvailable),
            )


class DownloadRib(LoggedPage, MyHTMLPage):
    def get_rib_value(self, acc_id):
        opt = self.doc.xpath('//select[@id="idxSelection"]/optgroup//option')
        for o in opt:
            if acc_id in o.text:
                return o.xpath('./@value')[0]
        return None


class RibPage(LoggedPage, MyHTMLPage):
    def get_iban(self):
        if self.doc.xpath('//div[@class="blocbleu"][2]//table[@class="datalist"]'):
            return CleanText()\
                .filter(self.doc.xpath('//div[@class="blocbleu"][2]//table[@class="datalist"]')[0])\
                .replace(' ', '').strip()
        return None

    @method
    class get_profile(ItemElement):
        klass = Company

        obj_name = CleanText('//table[@class="datalistecart"]//td[@class="nom"]')
        obj_address = CleanText('//table[@class="datalistecart"]//td[@class="adr"]')
