# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import api, fields, models
from odoo.exceptions import UserError
import pytz
from datetime import timedelta


class ReportSaleDetails(models.AbstractModel):

    _name = 'report.custom_tireston.report_saledetails'

    @api.model
    def get_sale_details(self, report_date=False,  companies=False):
        """ Serialise the orders of the day information

        params: date_start, date_stop string representing the datetime of order
        """

#         user_tz = pytz.timezone(self.env.context.get(
#             'tz') or self.env.user.tz or 'UTC')
#         today = user_tz.localize(fields.Datetime.from_string(
#             fields.Date.context_today(self)))
#         today = today.astimezone(pytz.timezone('UTC'))
        report_date = fields.Datetime.from_string(report_date)
        date_start = report_date + timedelta(days=0, seconds=0)

        date_stop = report_date + timedelta(days=1, seconds=-1)
        date_stop = max(date_stop, date_start)
        date_start = fields.Datetime.to_string(date_start)
        date_stop = fields.Datetime.to_string(date_stop)

        orders = self.env['sale.order'].search([
            ('date_order', '>=', date_start),
            ('date_order', '<=', date_stop),
            ('state', 'in', ['sale']),
            ('company_id', 'in', companies.ids)])

        user_currency = self.env.user.company_id.currency_id

        total = 0.0
        products_sold = {}
        taxes = {}
        payments = {}
        for order in orders:
            if user_currency != order.pricelist_id.currency_id:
                total += order.pricelist_id.currency_id.compute(
                    order.amount_total, user_currency)
            else:
                total += order.amount_total

            for line in order.order_line:
                key = (line.product_id, line.price_unit, line.discount)
                products_sold.setdefault(key, 0.0)
                products_sold[key] += line.product_uom_qty

            invoice_ids = order.order_line.mapped('invoice_lines').mapped(
                'invoice_id').filtered(lambda r: r.type in ['out_invoice', 'out_refund'])
            # Search for invoices which have been 'cancelled' (filter_refund = 'modify' in
            # 'account.invoice.refund')
            # use like as origin may contains multiple references (e.g. 'SO01,
            # SO02')
            refunds = invoice_ids.search([('origin', 'like', order.name)]).filtered(
                lambda r: r.type in ['out_invoice', 'out_refund'])
            invoice_ids |= refunds.filtered(lambda r: order.name in [
                                            origin.strip() for origin in r.origin.split(',')])
            # Search for refunds as well
            refund_ids = self.env['account.invoice'].browse()
            if invoice_ids:
                for inv in invoice_ids:
                    refund_ids += refund_ids.search([('type', '=', 'out_refund'), ('origin', '=',
                                                                                   inv.number), ('origin', '!=', False), ('journal_id', '=', inv.journal_id.id)])

            invoices = invoice_ids + refund_ids
            for invoice in invoices:
                for tax in invoice.tax_line_ids:
                    if taxes.get(tax.tax_id.id):
                        taxes[tax.tax_id.id]['total'] += tax.amount
                    else:
                        taxes.setdefault(
                            tax.tax_id.id, {'name': tax.name, 'total': tax.amount})
                for payment in invoice.payment_move_line_ids:
                    if payments.get(payment.journal_id.id):
                        payments[payment.journal_id.id]['total'] += payment.credit
                    else:
                        payments.setdefault(
                            payment.journal_id.id, {'name': payment.journal_id.name, 'total': payment.credit})
#

        return {
            'total_paid': user_currency.round(total),
            'payments': payments.values(),
            'company_name': self.env.user.company_id.name,
            'taxes': taxes.values(),
            'report_date': report_date,
            'products': sorted([{
                'product_id': product.id,
                'product_name': product.name,
                'code': product.default_code,
                'quantity': qty,
                'price_unit': price_unit,
                'discount': discount,
                'uom': product.uom_id.name
            } for (product, price_unit, discount), qty in products_sold.items()], key=lambda l: l['product_name'])
        }

    @api.multi
    def render_html(self, docids, data=None):
        data = dict(data or {})
        companies = self.env['res.company'].browse(data['company_ids'])
        data.update(self.get_sale_details(
            data['report_date'], companies))
        return self.env['report'].render('custom_tireston.report_saledetails_doc', data)


class SaleDetails(models.TransientModel):
    _name = 'sale.details.wizard'
    _description = 'Open Sale Details Report'

    report_date = fields.Date(required=True, default=fields.Date.today)
    company_ids = fields.Many2many('res.company')

    @api.multi
    def generate_report(self):
        data = {'report_date': self.report_date,
                'company_ids': self.company_ids.ids}
        return self.env['report'].get_action(
            [], 'custom_tireston.report_saledetails', data=data)
