# 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 copy
import os

from passerelle.contrib.utils import axel

BASE_XSD_PATH = os.path.join(os.path.dirname(__file__), 'xsd')


class Operation(axel.Operation):
    base_xsd_path = BASE_XSD_PATH
    default_prefix = 'Dui/'


ref_date_gestion_dui = Operation('RefDateGestionDui')
ref_verif_dui = Operation('RefVerifDui')
ref_famille_dui = Operation('RefFamilleDui')
form_maj_famille_dui = Operation('FormMajFamilleDui')
form_paiement_dui = Operation('FormPaiementDui')
ref_facture_a_payer = Operation('RefFactureAPayer')
ref_facture_pdf = Operation('RefFacturePDF', prefix='')
list_dui_factures = Operation('ListeDuiFacturesPayeesRecettees', request_root_element='LISTFACTURE')
enfants_activites = Operation('EnfantsActivites', request_root_element='DUI')
reservation_periode = Operation('ReservationPeriode')
reservation_annuelle = Operation('ReservationAnnuelle')


PAYMENT_SCHEMA = {
    'type': 'object',
    'properties': {
        'transaction_date': copy.deepcopy(axel.datetime_type),
        'transaction_id': {
            'type': 'string',
        },
    },
    'required': ['transaction_date', 'transaction_id'],
}

LINK_SCHEMA = copy.deepcopy(ref_verif_dui.request_schema['properties']['PORTAIL']['properties']['DUI'])
LINK_SCHEMA['properties'].pop('IDPERSONNE')
LINK_SCHEMA['required'].remove('IDPERSONNE')

UPDATE_FAMILY_FLAGS = {
    'maj:adresse': 'ADRESSE',
    'maj:rl1': 'RL1',
    'maj:rl1_adresse_employeur': 'RL1/ADREMPLOYEUR',
    'maj:rl2': 'RL2',
    'maj:rl2_adresse_employeur': 'RL2/ADREMPLOYEUR',
    'maj:revenus': 'REVENUS',
}
UPDATE_FAMILY_REQUIRED_FLAGS = [
    'maj:adresse',
    'maj:rl1',
    'maj:rl2',
    'maj:revenus',
]
for i in range(0, 6):
    UPDATE_FAMILY_FLAGS.update(
        {
            'maj:enfant_%s' % i: 'ENFANT/%s' % i,
            'maj:enfant_%s_sanitaire' % i: 'ENFANT/%s/SANITAIRE' % i,
            'maj:enfant_%s_sanitaire_medecin' % i: 'ENFANT/%s/SANITAIRE/MEDECIN' % i,
            'maj:enfant_%s_sanitaire_vaccin' % i: 'ENFANT/%s/SANITAIRE/VACCIN' % i,
            'maj:enfant_%s_sanitaire_allergie' % i: 'ENFANT/%s/SANITAIRE/ALLERGIE' % i,
            'maj:enfant_%s_sanitaire_handicap' % i: 'ENFANT/%s/SANITAIRE/HANDICAP' % i,
            'maj:enfant_%s_assurance' % i: 'ENFANT/%s/ASSURANCE' % i,
            'maj:enfant_%s_contact' % i: 'ENFANT/%s/CONTACT' % i,
        }
    )
    UPDATE_FAMILY_REQUIRED_FLAGS.append('maj:enfant_%s' % i)

UPDATE_FAMILY_SCHEMA = copy.deepcopy(
    form_maj_famille_dui.request_schema['properties']['PORTAIL']['properties']['DUI']
)

for flag in sorted(UPDATE_FAMILY_FLAGS.keys()):
    flag_type = copy.deepcopy(axel.boolean_type)
    if flag not in UPDATE_FAMILY_REQUIRED_FLAGS:
        flag_type['oneOf'].append({'type': 'null'})
        flag_type['oneOf'].append({'type': 'string', 'enum': ['']})
    UPDATE_FAMILY_SCHEMA['properties'][flag] = flag_type
    UPDATE_FAMILY_SCHEMA['required'].append(flag)

UPDATE_FAMILY_SCHEMA['properties'].pop('IDDUI')
UPDATE_FAMILY_SCHEMA['properties'].pop('DATEDEMANDE')
UPDATE_FAMILY_SCHEMA['properties'].pop('QUIACTUALISEDUI')
UPDATE_FAMILY_SCHEMA['required'].remove('IDDUI')
UPDATE_FAMILY_SCHEMA['required'].remove('DATEDEMANDE')
UPDATE_FAMILY_SCHEMA['required'].remove('QUIACTUALISEDUI')
for key in ['IDPERSONNE', 'NOM', 'PRENOM', 'NOMJEUNEFILLE', 'DATENAISSANCE', 'CIVILITE', 'INDICATEURRL']:
    UPDATE_FAMILY_SCHEMA['properties']['RL1']['properties'].pop(key)
    UPDATE_FAMILY_SCHEMA['properties']['RL1']['required'].remove(key)
    UPDATE_FAMILY_SCHEMA['properties']['RL2']['properties'].pop(key)
    UPDATE_FAMILY_SCHEMA['properties']['RL2']['required'].remove(key)
UPDATE_FAMILY_SCHEMA['properties']['REVENUS']['properties'].pop('NBENFANTSACHARGE')
UPDATE_FAMILY_SCHEMA['properties']['REVENUS']['required'].remove('NBENFANTSACHARGE')

handicap_fields = [
    'AUTREDIFFICULTE',
    'ECOLESPECIALISEE',
    'INDICATEURAUXILIAIREVS',
    'INDICATEURECOLE',
    'INDICATEURHANDICAP',
    'INDICATEURNOTIFMDPH',
]
sanitaire_properties = UPDATE_FAMILY_SCHEMA['properties']['ENFANT']['items']['properties']['SANITAIRE'][
    'properties'
]
sanitaire_required = UPDATE_FAMILY_SCHEMA['properties']['ENFANT']['items']['properties']['SANITAIRE'][
    'required'
]
sanitaire_properties['HANDICAP'] = {
    'type': 'object',
    'properties': {},
    'required': handicap_fields,
}
sanitaire_required.append('HANDICAP')
for key in handicap_fields:
    field = sanitaire_properties.pop(key)
    sanitaire_properties['HANDICAP']['properties'][key] = field
    sanitaire_required.remove(key)

sanitaire_properties.pop('ALLERGIE')
sanitaire_properties['ALLERGIE'] = {
    'type': 'object',
    'properties': {},
    'required': ['ASTHME', 'MEDICAMENTEUSES', 'ALIMENTAIRES', 'AUTRES'],
}
sanitaire_required.append('ALLERGIE')
for key in ['ASTHME', 'MEDICAMENTEUSES', 'ALIMENTAIRES']:
    flag_type = copy.deepcopy(axel.boolean_type)
    flag_type['oneOf'].append({'type': 'null'})
    flag_type['oneOf'].append({'type': 'string', 'enum': ['']})
    sanitaire_properties['ALLERGIE']['properties'][key] = flag_type
sanitaire_properties['ALLERGIE']['properties']['AUTRES'] = {
    'oneOf': [
        {'type': 'null'},
        {
            'type': 'string',
            'minLength': 0,
            'maxLength': 50,
        },
    ]
}

UPDATE_FAMILY_SCHEMA['unflatten'] = True

BOOKING_SCHEMA = {
    'type': 'object',
    'properties': {
        'booking_start_date': copy.deepcopy(axel.date_type),
        'booking_end_date': copy.deepcopy(axel.date_type),
        'booking_list_MAT': {
            'oneOf': [
                {'type': 'null'},
                {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'pattern': '[A-Za-z0-9]+:MAT:[A-Za-z0-9]+:[0-9]{4}-[0-9]{2}-[0-9]{2}',
                    },
                },
            ]
        },
        'booking_list_MIDI': {
            'oneOf': [
                {'type': 'null'},
                {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'pattern': '[A-Za-z0-9]+:MIDI:[A-Za-z0-9]+:[0-9]{4}-[0-9]{2}-[0-9]{2}',
                    },
                },
            ]
        },
        'booking_list_SOIR': {
            'oneOf': [
                {'type': 'null'},
                {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'pattern': '[A-Za-z0-9]+:SOIR:[A-Za-z0-9]+:[0-9]{4}-[0-9]{2}-[0-9]{2}',
                    },
                },
            ]
        },
        'booking_list_GARD': {
            'oneOf': [
                {'type': 'null'},
                {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'pattern': '[A-Za-z0-9]+:GARD:[A-Za-z0-9]+:[0-9]{4}-[0-9]{2}-[0-9]{2}',
                    },
                },
            ]
        },
        'child_id': {
            'type': 'string',
            'minLength': 1,
            'maxLength': 8,
        },
        'regime': {'oneOf': [{'type': 'null'}, {'type': 'string', 'enum': ['', 'SV', 'AV']}]},
    },
    'required': [
        'booking_start_date',
        'booking_end_date',
        'booking_list_MAT',
        'booking_list_MIDI',
        'booking_list_SOIR',
        'booking_list_GARD',
        'child_id',
    ],
}


ANNUAL_BOOKING_SCHEMA = {
    'type': 'object',
    'properties': {
        'booking_list_MAT': {
            'oneOf': [
                {'type': 'null'},
                {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'pattern': '[A-Za-z0-9]+:MAT:[A-Za-z0-9]+:(monday|tuesday|wednesday|thursday|friday)',
                    },
                },
            ]
        },
        'booking_list_MIDI': {
            'oneOf': [
                {'type': 'null'},
                {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'pattern': '[A-Za-z0-9]+:MIDI:[A-Za-z0-9]+:(monday|tuesday|wednesday|thursday|friday)',
                    },
                },
            ]
        },
        'booking_list_SOIR': {
            'oneOf': [
                {'type': 'null'},
                {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'pattern': '[A-Za-z0-9]+:SOIR:[A-Za-z0-9]+:(monday|tuesday|wednesday|thursday|friday)',
                    },
                },
            ]
        },
        'booking_list_GARD': {
            'oneOf': [
                {'type': 'null'},
                {
                    'type': 'array',
                    'items': {
                        'type': 'string',
                        'pattern': '[A-Za-z0-9]+:GARD:[A-Za-z0-9]+:(monday|tuesday|wednesday|thursday|friday)',
                    },
                },
            ]
        },
        'child_id': {
            'type': 'string',
            'minLength': 1,
            'maxLength': 8,
        },
        'regime': {'oneOf': [{'type': 'null'}, {'type': 'string', 'enum': ['', 'SV', 'AV']}]},
        'booking_date': copy.deepcopy(axel.date_type),
    },
    'required': [
        'booking_list_MAT',
        'booking_list_MIDI',
        'booking_list_SOIR',
        'booking_list_GARD',
        'child_id',
        'booking_date',
    ],
}
