# Copyright 2020-2022 Le Filament (<https://le-filament.com>)
# License AGPL-3 or later (http://www.gnu.org/licenses/agpl.html).

import csv
from datetime import date, datetime
from io import BytesIO, StringIO
from odoo.addons.lefilament_export_journal_tool.controllers.main import JournalDatasExport
from odoo import http
from odoo.http import request
from odoo.tools.misc import xlwt
from odoo.tools.safe_eval import safe_eval

from odoo.addons.web.controllers.main import content_disposition, serialize_exception


class JournalDatasExport(JournalDatasExport):
    # ------------------------------------------------------
    # Routes
    # ------------------------------------------------------
    @http.route("/web/export_journal/", type="http", auth="user")
    @serialize_exception
    def export_journal(
        self, export_format, export, export_type, date_start, date_end, **kwargs
    ):
        """
        Sélectionne les account.move.line correspondants aux journaux
        et à la plage de date définis
        Crée le lignes de valeurs
        :param export_format: xls/csv
        :param export: id export.journal.type
        :param export_type: empty (not already exported lines) / all
        :param date_start: date
        :param date_end: date
        :return: file
        """
        export_id = request.env["export.journal.type"].browse(int(export))
        domain = [
            ("date", ">=", date_start),
            ("date", "<=", date_end),
            ("journal_id", "in", export_id.journal_ids.ids),
            ("company_id", "=", export_id.company_id.id),
        ]
        if export_type == "empty":
            domain += [("date_export", "=", False)]
        if export_id.export_domain:
            domain += safe_eval(export_id.export_domain)
        export_line_ids = request.env["account.move.line"].search(domain)
        export_line_grouped_by_invoice = {}
        for el in export_line_ids:
            if not export_line_grouped_by_invoice.get(el.move_id.name):
                export_line_grouped_by_invoice[el.move_id.name] = []
            export_line_grouped_by_invoice[el.move_id.name].append(el)
        lines_to_export = []
        initial_sum_line = ['' for _ in range(len(export_id.fields_ids))]
        sum_line = initial_sum_line[:]
        big_sum_line = None

        for invoice_name, move_lines in export_line_grouped_by_invoice.items():
            for line in move_lines:
                row = []
                for key,field in enumerate(export_id.fields_ids):
                    if field.is_python:
                        value = safe_eval(field["field_name"], {"line": line}, mode="eval")
                        if field.is_sum and value:
                            if sum_line[key] == '':
                                sum_line[key] = 0
                            sum_line[key] += float(value)
                    else:
                        value = safe_eval(field["field_name"])
                    row.append(value)
                lines_to_export.append(row)
                line.write({"date_export": datetime.now()})
            lines_to_export.append(sum_line)
            if not big_sum_line:
                # Initialise bigsum to the same size and value of the sum_line
                # So it has not to be initialized with list of empty string
                big_sum_line = sum_line[:]
            else:
                big_sum_line = [value + sum_line[i] for i, value in
                                enumerate(big_sum_line)]
            sum_line = initial_sum_line[:]
        else:
            lines_to_export.append(big_sum_line)

        filename_ = (
            export_id.company_id.name.title().replace(" ", "")
            + date_start.replace("-", "")
            + "_"
            + date_end.replace("-", "")
        )

        if export_format == "csv":
            return self.export_csv(export_id, lines_to_export, filename_)
        elif export_format == "xls":
            return self.export_xls(export_id, lines_to_export, filename_)

    # ------------------------------------------------------
    # Common function
    # ------------------------------------------------------