# passerelle - uniform access to multiple data sources and services
# Copyright (C) 2020  Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import datetime
from collections import OrderedDict

from passerelle.utils.conversion import normalize

situation_familiale_mapping = OrderedDict(
    [
        ('C', 'Célibataire'),
        ('D', 'Divorcé (e)'),
        ('M', 'Marié (e)'),
        ('S', 'Séparé (e)'),
        ('V', 'Veuf (ve)'),
        ('VM', 'Vie maritale'),
        ('P', 'Pacs'),
    ]
)

csp_mapping = OrderedDict(
    [
        ('OUV', 'Ouvriers'),
        ('EMP', 'Employés'),
        ('ETU', 'Etudiants'),
        ('RET', 'Retraités'),
        ('STA', 'Personnes en stage'),
        ('AGEX', 'Agriculteurs exploitants'),
        ('ARCO', 'Artisans commercants chefs entreprise'),
        ('CADP', 'Cadres professions intellectuelles supérieures'),
        ('PRIN', 'Professions intermediaires'),
        ('SACT', 'Autres personnes sans activité professionnelle'),
        ('REC', 'Recherche emploi'),
    ]
)

lien_parente_mapping = OrderedDict(
    [
        ('GRP1', 'Grands-parents paternels'),
        ('GRP2', 'Grands-parents maternels'),
        ('VOI', 'Voisin'),
        ('FRE', "Frère de l'enfant"),
        ('SOE', "Soeur de l'enfant"),
        ('AMI', 'Ami (e)'),
        ('FAMI', 'Membre de la famille'),
        ('BABY', 'Baby sitter'),
    ]
)

type_regime_mapping = OrderedDict(
    [
        ('GENE', 'Régime général'),
        ('ZAU', 'Autre'),
        ('MSA', 'MSA'),
    ]
)

regime_mapping = OrderedDict(
    [
        ('AV', 'Menu avec viande'),
        ('SV', 'Menu sans viande'),
    ]
)


def get_label(mapping, code):
    return mapping.get(code, code)


def upperize(data):
    if isinstance(data, dict):
        for key, val in data.items():
            data[key] = upperize(val)
    if isinstance(data, list):
        for i, val in enumerate(data):
            data[i] = upperize(val)
    if isinstance(data, str):
        data = normalize(data).upper()
    return data


def normalize_invoice(invoice, dui, historical=False, vendor_base=None):
    vendor = vendor_base or {}
    vendor.update(invoice)
    invoice_id = '%s-%s' % (dui, invoice['IDFACTURE'])
    if historical:
        invoice_id = 'historical-%s' % invoice_id
    data = {
        'id': invoice_id,
        'display_id': str(invoice['IDFACTURE']),
        'label': invoice['LIBELLE'],
        'paid': False,
        'vendor': {'toulouse-axel': vendor},
    }
    if historical:
        data.update(
            {
                'amount': 0,
                'total_amount': invoice['MONTANT'],
                'created': invoice['EMISSION'],
                'pay_limit_date': '',
                'online_payment': False,
                'has_pdf': invoice['IPDF'] == 'O',
            }
        )
    else:
        data.update(
            {
                'amount': invoice['RESTEAPAYER'],
                'total_amount': invoice['MONTANTTOTAL'],
                'amount_paid': max(0, invoice['MONTANTTOTAL'] - invoice['RESTEAPAYER']) or '',
                'created': invoice['DATEEMISSION'],
                'pay_limit_date': invoice['DATEECHEANCE'],
                'online_payment': bool(invoice['RESTEAPAYER'] > 0),
                'has_pdf': invoice['EXISTEPDF'] == '1',
            }
        )
    return data


def get_reference_year_from_date(booking_date):
    if booking_date.month <= 7:
        # between january and july, reference year is the year just before
        return booking_date.year - 1
    return booking_date.year


def get_week_dates_from_date(booking_date):
    day = booking_date.weekday()
    # return monday and friday of the week
    return (booking_date - datetime.timedelta(days=day), booking_date + datetime.timedelta(days=4 - day))


def get_booking(value):
    # 0: no registration
    # 1: registration
    # 2: not applicable (example: GARDERIE is applicable only on wednesday)
    if value == '2':
        return None
    return value == '1'
