# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from stdnum import get_cc_module

try:
    import phonenumbers
    from phonenumbers import NumberParseException, PhoneNumberFormat
except ImportError:
    phonenumbers = None

from trytond.i18n import gettext
from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.tools import remove_forbidden_chars

from .exceptions import BadRequest
from .web import join_name, split_name


class Address(metaclass=PoolMeta):
    __name__ = 'party.address'

    vsf_telephone = fields.Many2One(
        'party.contact_mechanism', "Telephone",
        domain=[
            ('party', '=', Eval('party', -1)),
            ('type', 'in', ['phone', 'mobile']),
            ])

    def get_vsf(self, for_party=None):
        if for_party and for_party != self.party:
            firstname, lastname = split_name(
                self.party_name or for_party.name)
        else:
            firstname, lastname = split_name(
                self.party_name or self.party.name)
        address = {
            'id': self.id,
            'firstname': firstname,
            'lastname': lastname,
            'street': self.street.splitlines(),
            'city': self.city,
            'country_id': self.country.code if self.country else None,
            'postcode': self.postal_code,
            }
        if self.subdivision:
            address['region'] = {
                'region': self.subdivision.name,
                }
        if self.vsf_telephone:
            address['telephone'] = self.vsf_telephone.value
        if for_party:
            address['company'] = self.party.name
            address['vat_id'] = (
                self.party.tax_identifier.code_compact
                if self.party.tax_identifier else None)
        return address

    def set_vsf(self, data, for_party=None):
        pool = Pool()
        Country = pool.get('country.country')
        Subdivision = pool.get('country.subdivision')
        ContactMechanism = pool.get('party.contact_mechanism')

        name = remove_forbidden_chars(
            join_name(data['firstname'], data['lastname']))
        party = for_party or self.party
        if name != party.name:
            self.party_name = name
        self.street = '\n'.join(map(str, data['street']))
        self.city = remove_forbidden_chars(data['city'])
        if data['country_id']:
            try:
                self.country, = Country.search([
                        ('code', '=', data['country_id']),
                        ], limit=1)
            except ValueError:
                raise BadRequest(gettext(
                        'web_shop_vue_storefront.msg_unknown_country_code',
                        code=data['country_id']))
        self.postal_code = data['postcode']

        if data.get('region') and data['region']['region']:
            domain = [
                ('name', '=', data['region']['region']),
                ]
            if self.country:
                domain.append(('country', '=', self.country.id))
            subdivisions = Subdivision.search(domain, limit=1)
            if subdivisions:
                self.subdivision, = subdivisions

        if data.get('telephone'):
            value = remove_forbidden_chars(data['telephone'])
            if phonenumbers:
                try:
                    phonenumber = phonenumbers.parse(
                        data['telephone'], data['country_id'])
                    value = phonenumbers.format_number(
                        phonenumber, PhoneNumberFormat.INTERNATIONAL)
                except NumberParseException:
                    pass
            contacts = ContactMechanism.search([
                    ('party', '=', self.party.id),
                    ('type', 'in', ['phone', 'mobile']),
                    ('value', '=', value),
                    ], limit=1)
            if contacts:
                self.vsf_telephone, = contacts
            else:
                contact = ContactMechanism(
                    party=self.party,
                    type='phone',
                    value=value)
                contact.save()
                self.vsf_telephone = contact


class Identifier(metaclass=PoolMeta):
    __name__ = 'party.identifier'

    def set_vsf_tax_identifier(self, code):
        pool = Pool()
        Party = pool.get('party.party')
        for type in Party.tax_identifier_types():
            module = get_cc_module(*type.split('_', 1))
            if module and module.is_valid(code):
                self.type = type
                self.code = code
                break
        else:
            raise BadRequest(gettext(
                    'web_shop_vue_storefront.msg_invalid_tax_identifier',
                    code=code))
