# © 2021 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import base64
import csv
import mimetypes
from io import StringIO

from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.tools.mimetypes import guess_mimetype


class ScopImportIDFWizard(models.TransientModel):
    _name = "scop.invoice.idf.wizard"
    _description = "Wizard: Importer les cotisations ou factures IDF"

    # ------------------------------------------------------
    # Fields declaration
    # ------------------------------------------------------
    file = fields.Binary("Fichier CSV", required=True)
    filename = fields.Char("Filename")
    type = fields.Selection(
        string="Type",
        selection=[
            ("inv", "Facture"),
            ("cotiz", "Cotisation"),
        ],
        required=False,
    )

    # ------------------------------------------------------
    # Actions
    # ------------------------------------------------------
    @api.model
    def scop_invoice_idf_wizard_action(self):
        return {
            "type": "ir.actions.act_window",
            "name": "Import Factures",
            "views": [
                [
                    self.env.ref("cgscop_invoice_idf.scop_invoice_idf_wizard_form").id,
                    "form",
                ]
            ],
            "context": {
                "default_type": "inv",
            },
            "res_model": "scop.invoice.idf.wizard",
            "target": "new",
        }

    @api.model
    def scop_cotisation_idf_wizard_action(self):
        return {
            "type": "ir.actions.act_window",
            "name": "Import Cotisations",
            "views": [
                [
                    self.env.ref("cgscop_invoice_idf.scop_invoice_idf_wizard_form").id,
                    "form",
                ]
            ],
            "context": {
                "default_type": "cotiz",
            },
            "res_model": "scop.invoice.idf.wizard",
            "target": "new",
        }

    def load_data(self):
        """
        Load CSV File and write datas into the database
        :return:
        """
        # Get Mimetype
        content_type = mimetypes.guess_type(self.filename)
        if content_type[0]:
            content_type = content_type[0]
        else:
            content_type = guess_mimetype(str(self.file))

        if content_type != "text/csv":
            raise UserError(_("This file does not seem to be a CSV file"))

        file = StringIO(base64.b64decode(self.file).decode("ISO-8859-1"))
        reader = csv.DictReader(file, delimiter=";")

        company_id = self.env.company
        line = 1
        tried_lines = 0
        success = 0
        logs = "<ul>"
        new_log = self.env["scop.invoice.idf.logs"].create({"logs": logs})
        new_lines_years = set()

        if self.type == "inv":
            model = "scop.invoice.idf"
        else:
            model = "scop.cotisation.idf"

        for row in reader:
            line += 1
            journal = row["Journal"]
            if journal in ["VE", "BFC"]:
                tried_lines += 1
                compte = row["Compte"]
                partner_id = self.env["res.partner"].search(
                    [
                        ["member_number_int", "=", int(compte[2:7])],
                        ["member_number_int", "!=", 0],
                    ]
                )
                if len(partner_id) != 1:
                    logs += (
                        "<li> Ligne "
                        + str(line)
                        + ": Impossible de rattacher le compte "
                        + compte
                        + "</li>"
                    )
                else:
                    writing_date = row["Date écriture"]
                    libelle = row["Libellé écriture"]
                    existing_import_line = self.env[model].search(
                        [
                            ["partner_id", "=", partner_id.id],
                            ["writing_date", "=", writing_date],
                            ["journal", "=", journal],
                            ["name", "=", libelle],
                        ]
                    )
                    if len(existing_import_line) > 0:
                        logs += "<li> Ligne " + str(line) + ": Doublon</li>"
                    else:
                        debit = float(row['Débit euro'].replace(',','.'))
                        credit = float(row['Crédit euro'].replace(',','.'))
                        if debit > 0 and credit > 0:
                            logs += (
                                "<li> Ligne " + str(line) + ": Montants incorrects</li>"
                            )
                        else:
                            if journal == "VE" and debit > 0:
                                line_type = "inv"
                            elif journal == "BFC" and credit > 0:
                                line_type = "pay"
                            elif journal == "BFC" and debit > 0:
                                line_type = "reject"
                                credit = debit * (-1)
                                debit = 0
                            else:
                                line_type = "refund"

                            lettrage = row["Lettrage N"]
                            year = row["Année"]
                            acc_doc = row["Pièce"]

                            values = {
                                "company_id": company_id.id,
                                "partner_id": partner_id.id,
                                "journal": journal,
                                "writing_date": writing_date,
                                "acc_doc": acc_doc,
                                "name": libelle,
                                "year": year,
                                "type": line_type,
                                "lettrage": lettrage,
                                "debit": debit,
                                "credit": credit,
                            }
                            new_line = self.env[model].create(values)
                            success += 1
                            new_lines_years.add(new_line.year)
            logs += "</ul>"

        new_log.write(
            {
                "type": self.type,
                "logs": logs,
                "success": success,
                "failure": tried_lines - success,
            }
        )
        # Lettrage for all line in updated years
        recordset_for_lettrage = self.env[model].search(
            [["year", "in", list(new_lines_years)]]
        )
        recordset_for_lettrage.reconcile()
        return {
            "type": "ir.actions.act_window",
            "views": [[False, "form"]],
            "view_mode": "form",
            "res_model": "scop.invoice.idf.logs",
            "target": "current",
            "res_id": new_log.id,
        }