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

import csv
from datetime import date
from io import BytesIO, StringIO

from odoo import http
from odoo.http import request
from odoo.addons.web.controllers.main import serialize_exception
from odoo.addons.web.controllers.main import content_disposition
from odoo.tools.misc import xlwt


class JournalDatasExport(http.Controller):
    # ------------------------------------------------------
    # Routes
    # ------------------------------------------------------
    @http.route('/web/export_journal/', type='http', auth="user")
    @serialize_exception
    def export_journal(self, format, export, 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 format: xls/csv
        :param export: id export.journal.type
        :param date_start: date
        :param date_end: date
        :return: file
        """
        export_id = request.env['export.journal.type'].browse(int(export))
        export_line_ids = request.env['account.move.line'].search([
            ('date', '>=', date_start),
            ('date', '<=', date_end),
            ('journal_id', 'in', export_id.journal_ids.ids),
            ('company_id', '=', export_id.company_id.id),
        ])
        lines_to_export = []
        for line in export_line_ids:
            row = []
            for field in export_id.fields_ids:
                value = eval(field.field_name)
                row.append(value)
            lines_to_export.append(row)

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

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

    # ------------------------------------------------------
    # Common function
    # ------------------------------------------------------
    def export_csv(self, export_id, lines_to_export, filename_):
        fp = StringIO()
        export_file = csv.writer(
            fp,
            delimiter=export_id.delimiter,
            quoting=csv.QUOTE_ALL)
        # Add header line
        if export_id.is_header:
            row = []
            for head in export_id.fields_ids.mapped('name'):
                row.append(head)
            export_file.writerow(row)

        for line in lines_to_export:
            # Format date value
            line_values = [
                value if not isinstance(value, date) else value.strftime(
                    export_id.csv_datestyle) for value in line]
            export_file.writerow(line_values)

        fp.seek(0)
        data = fp.read()
        fp.close()

        filename = filename_ + '.csv'
        csvhttpheaders = [
            ('Content-Type', 'text/csv;charset=utf8'),
            ('Content-Disposition', content_disposition(filename)),
        ]
        return request.make_response(data, headers=csvhttpheaders)

    def export_xls(self, export_id, lines_to_export, filename_):
        workbook = xlwt.Workbook()
        worksheet = workbook.add_sheet(filename_)
        base_style = xlwt.easyxf('align: wrap yes')
        date_style = xlwt.XFStyle()
        date_style.num_format_str = export_id.xls_datestyle

        if export_id.is_header:
            for i, fieldname in enumerate(export_id.fields_ids.mapped('name')):
                worksheet.write(0, i, fieldname)
                worksheet.col(i).width = 4000  # around 220 pixels

        for row_index, line in enumerate(lines_to_export):
            for cell_index, value in enumerate(line):
                cell_style = base_style
                if isinstance(value, date):
                    cell_style = date_style
                worksheet.write(row_index + 1, cell_index, value, cell_style)
        fp = BytesIO()
        workbook.save(fp)
        fp.seek(0)
        data = fp.read()
        fp.close()
        filename = filename_ + '.xls'
        xlshttpheaders = [
            ('Content-Type', 'text/csv;charset=utf8'),
            ('Content-Disposition', content_disposition(filename)),
        ]
        return request.make_response(data, headers=xlshttpheaders)