# This file is part of Presik.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from datetime import datetime
from decimal import Decimal

from trytond.pool import Pool
from trytond.wizard import Wizard, StateView, Button, StateReport
from trytond.report import Report
from trytond.model import ModelView, fields
from trytond.transaction import Transaction

_ZERO = Decimal(0)


class InvoiceIncomeDailyStart(ModelView):
    'Invoice Income Daily Start'
    __name__ = 'hotel.invoice_income_daily.start'
    company = fields.Many2One('company.company', 'Company', required=True)
    invoice_date = fields.Date('Invoice Date', required=True)
    user = fields.Many2One('res.user', 'User', required=True)
    shop = fields.Many2One('sale.shop', 'Shop', required=True)
    # journal = fields.Many2One('account.statement.journal', 'Journal')

    @staticmethod
    def default_company():
        return Transaction().context.get('company')

    @staticmethod
    def default_sale_date():
        Date = Pool().get('ir.date')
        return Date.today()


class InvoiceIncomeDaily(Wizard):
    'Invoice Income Daily'
    __name__ = 'hotel.invoice_income_daily'
    start = StateView(
        'hotel.invoice_income_daily.start',
        'hotel.invoice_income_daily_start_view_form', [
            Button('Cancel', 'end', 'tryton-cancel'),
            Button('Print', 'print_', 'tryton-ok', default=True),
            ])
    print_ = StateReport('hotel.invoice_income_daily_report')

    def do_print_(self, action):
        report_context = {
            'company': self.start.company.id,
            'invoice_date': self.start.invoice_date,
            'user': self.start.user.id,
            'shop': self.start.shop.id,
        }
        return action, report_context

    def transition_print_(self):
        return 'end'


class InvoiceIncomeDailyReport(Report):
    'Invoice Income Daily Report'
    __name__ = 'hotel.invoice_income_daily_report'

    @classmethod
    def get_context(cls, records, header, data):
        report_context = super().get_context(records, header, data)
        pool = Pool()
        Invoice = pool.get('account.invoice')
        Company = pool.get('company.company')
        company = Company(data['company'])
        Statement = pool.get('account.statement')
        Shop = pool.get('sale.shop')
        User = pool.get('res.user')

        shop = Shop(data['shop'])
        statements = Statement.search([
            ('date', '=', data['invoice_date']),
            ('create_uid', '=', data['user']),
        ])
        user = User(data['user'])
        records = []
        advances = []
        statements_ = []
        total_advances = []
        advances_cash = []
        advances_electronic = []
        total_statements = []

        for statement in statements:
            st_amount = sum(li.amount for li in statement.lines)
            statements_.append({
                'id': statement.id,
                'sale_device': statement.sale_device.name,
                'journal': statement.journal.name,
                'turn': statement.turn,
                'total_amount': st_amount,
                'state': statement.state,
            })
            total_statements.append(st_amount)

            for li in statement.lines:
                sale = li.sale
                cash = 0
                electronic = 0
                if sale and not sale.invoice_number:
                    for pline in sale.payments:
                        if pline.statement.journal.kind == 'cash':
                            advances_cash.append(pline.amount)
                            cash = pline.amount
                        else:
                            electronic = pline.amount
                            advances_electronic.append(pline.amount)
                        advances.append({
                            'number': sale.number,
                            'reference': sale.reference,
                            'party': sale.party.name,
                            'total_amount': pline.amount,
                            'cash': cash,
                            'electronic': electronic,
                        })
                        total_advances.append(pline.amount)

        dom_ = [
            ('company', '=', data['company']),
            ('invoice_date', '=', data['invoice_date']),
            ('shop', '=', data['shop']),
            ('number', '!=', None),
            ('state', 'in', ['posted', 'paid', 'canceled']),
            ('create_uid', '=', data['user']),
        ]

        invoices = Invoice.search(dom_, order=[('number', 'ASC')])

        invoices_number = []
        total_invoices_cash = []
        total_invoices_electronic = []
        total_invoices_credit = []
        total_invoices_paid = []

        total_invoices_amount = []
        for invoice in invoices:
            invoices_number.append(invoice.number)
            cash = 0
            electronic = 0
            credit = 0
            total_invoices_amount.append(invoice.total_amount)
            sale = invoice.sales[0]
            if not sale.payments:
                total_invoices_credit.append(invoice.amount_to_pay)
                credit = invoice.amount_to_pay
            else:
                for p in sale.payments:
                    if p.statement.date == data['invoice_date']:
                        if p.statement.journal.kind == 'cash':
                            cash += p.amount
                            total_invoices_cash.append(p.amount)
                        else:
                            electronic += p.amount
                            total_invoices_electronic.append(p.amount)
                        total_invoices_paid.append(p.amount)

            inv = {
                'number': invoice.number,
                'reference': invoice.reference,
                'party': invoice.party.name,
                'total_amount': invoice.total_amount,
                'credit': credit,
                'cash': cash,
                'electronic': electronic,
                'paid': cash + electronic,
                'state': invoice.state_string,
            }
            records.append(inv)

        report_context['records'] = records
        report_context['advances'] = advances
        report_context['statements'] = statements_
        report_context['date'] = data['invoice_date']
        report_context['company'] = company.party.name
        report_context['shop'] = shop.name
        report_context['user'] = user.name
        report_context['print_date'] = datetime.now()
        report_context['total_invoices_amount'] = sum(total_invoices_amount)
        report_context['total_invoices_cash'] = sum(total_invoices_cash)
        report_context['total_invoices_electronic'] = sum(total_invoices_electronic)
        report_context['total_invoices_credit'] = sum(total_invoices_credit)
        report_context['total_invoices_paid'] = sum(total_invoices_paid)
        report_context['total_advances'] = sum(total_advances)
        report_context['advances_cash'] = sum(advances_cash)
        report_context['advances_electronic'] = sum(advances_electronic)
        report_context['total_statements'] = sum(total_statements)
        report_context['start_invoice'] = min(invoices_number) if invoices_number else ''
        report_context['end_invoice'] = max(invoices_number) if invoices_number else ''
        return report_context


class InvoiceSimplifiedReport(Report):
    __name__ = 'account.invoice_simplified'

    @classmethod
    def get_context(cls, records, header, data):
        report_context = super().get_context(records, header, data)
        Company = Pool().get('company.company')

        categories = {}
        if records:
            record = records[0]
            for l in record.lines:
                cat = l.product.template.account_category
                taxes = ''
                for tax in cat.customer_taxes_used:
                    taxes += tax.name + ' '

                if cat.id not in categories.keys():
                    categories[cat.id] = {
                        'description': cat.name,
                        'amount': l.amount,
                        'taxes': taxes
                    }
                else:
                    categories[cat.id]['amount'] += l.amount
            record._lines = categories.values()

        report_context['company'] = Company(Transaction().context['company'])
        return report_context
