import csv
from datetime import datetime

from django.core.management.base import BaseCommand, CommandError
from django.db import transaction

from eo_gestion.eo_banque.models import LigneBanquePop


class Command(BaseCommand):
    """
    Charge un fichier CSV exporté depuis notre banque en ligne Banque
    Populaire
    """

    can_import_django_settings = True
    output_transaction = True
    requires_system_checks = True
    args = '<csv_file> <csv_file>...'
    help = 'Charge les fichiers CSVs'
    HEADER = [
        'Compte',
        'Date de comptabilisation',
        'Date opération',
        'Libellé',
        'Référence',
        'Date valeur',
        'Montant',
    ]

    def add_arguments(self, parser):
        parser.add_argument("args", nargs="+")

    def to_date(self, str):
        try:
            return datetime.strptime(str, '%Y/%m/%d').date()
        except Exception:
            return datetime.strptime(str, '%d/%m/%Y').date()

    def make_csv_reader(self, csv_file):
        for delimiter in [";", "\t"]:
            csv_file.seek(0)
            csv_lines = csv.reader(csv_file, delimiter=delimiter)
            first_line = next(csv_lines)
            if first_line == self.HEADER:
                return csv_lines
        raise CommandError("Invalid CSV file header")

    def load_one_file(self, csv_file_path, csv_lines):
        counter = 0
        loaded = 0
        for line in csv_lines:
            compte, date_comptabilisation, date_operation, libelle, reference, date_valeur, montant, _ = line
            # utilise un point décimal
            montant = montant.replace(',', '.')
            date_comptabilisation = self.to_date(date_comptabilisation)
            date_operation = self.to_date(date_operation)
            date_valeur = self.to_date(date_valeur)
            ligne, created = LigneBanquePop.objects.get_or_create(
                compte=compte,
                date_comptabilisation=date_comptabilisation,
                date_operation=date_operation,
                libelle=libelle,
                reference=reference,
                date_valeur=date_valeur,
                montant=montant,
            )
            counter += 1
            if created:
                loaded += 1
                ligne.save()
        if loaded > 0:
            print(' - %s: read %s lines, loaded %s lines.' % (csv_file_path, counter, loaded))

    @transaction.atomic
    def handle(self, *args, **options):
        for csv_file_path in args:
            with open(csv_file_path, encoding='latin1') as csv_file:
                csv_lines = self.make_csv_reader(csv_file)
                self.load_one_file(csv_file_path, csv_lines)
