# -*- coding: utf-8 -*-
"""
Tax Reports
===========
- Payroll Tax Liability
- Payroll Tax Payments
- Payroll Tax and Wage Summary
"""

from odoo import api, fields, models, _


class PayrollReportTaxLiability(models.AbstractModel):
    """
    Payroll Tax Liability Report
    Shows tax amounts owed vs paid.
    """
    _name = 'payroll.report.tax.liability'
    _inherit = 'payroll.report'
    _description = 'Payroll Tax Liability Report'

    report_name = 'Payroll Tax Liability'
    report_code = 'tax_liability'
    filter_employee = False

    def _get_columns(self):
        return [
            {'name': _('Tax Type'), 'field': 'tax_type', 'type': 'char', 'sortable': True},
            {'name': _('Tax Amount'), 'field': 'tax_amount', 'type': 'monetary', 'sortable': True},
            {'name': _('Tax Paid'), 'field': 'tax_paid', 'type': 'monetary', 'sortable': True},
            {'name': _('Tax Owed'), 'field': 'tax_owed', 'type': 'monetary', 'sortable': True},
        ]

    def _get_lines(self, options):
        date_from = options.get('date', {}).get('date_from')
        date_to = options.get('date', {}).get('date_to')
        
        # Build domain for payslips
        domain = [
            ('state', 'in', ['done', 'paid']),
            ('company_id', '=', self.env.company.id),
        ]
        if date_from:
            domain.append(('date_from', '>=', date_from))
        if date_to:
            domain.append(('date_to', '<=', date_to))
        
        payslips = self.env['hr.payslip'].search(domain)
        
        # Calculate totals by tax type
        tax_totals = {
            'income_tax': {'name': _('Income Tax'), 'amount': 0, 'codes': ['FED_TAX', 'PROV_TAX']},
            'ei_employee': {'name': _('Employment Insurance'), 'amount': 0, 'codes': ['EI']},
            'ei_employer': {'name': _('Employment Insurance Employer'), 'amount': 0, 'codes': ['EI_ER']},
            'cpp_employee': {'name': _('Canada Pension Plan'), 'amount': 0, 'codes': ['CPP']},
            'cpp_employer': {'name': _('Canada Pension Plan Employer'), 'amount': 0, 'codes': ['CPP_ER']},
            'cpp2_employee': {'name': _('Second Canada Pension Plan'), 'amount': 0, 'codes': ['CPP2']},
            'cpp2_employer': {'name': _('Second Canada Pension Plan Employer'), 'amount': 0, 'codes': ['CPP2_ER']},
        }
        
        for slip in payslips:
            if not hasattr(slip, 'line_ids') or not slip.line_ids:
                continue
            for line in slip.line_ids:
                if not hasattr(line, 'code') or not line.code:
                    continue
                for key, data in tax_totals.items():
                    if line.code in data['codes']:
                        tax_totals[key]['amount'] += abs(line.total or 0)
        
        # Get paid amounts from remittances
        remittance_domain = [
            ('state', '=', 'paid'),
            ('company_id', '=', self.env.company.id),
        ]
        if date_from:
            remittance_domain.append(('period_start', '>=', date_from))
        if date_to:
            remittance_domain.append(('period_end', '<=', date_to))
        
        remittances = self.env['hr.tax.remittance'].search(remittance_domain)
        
        # Safely get remittance fields
        def safe_sum(records, field_name):
            if not records:
                return 0
            try:
                return sum(records.mapped(field_name)) or 0
            except:
                return 0
        
        paid_totals = {
            'income_tax': safe_sum(remittances, 'income_tax'),
            'ei_employee': safe_sum(remittances, 'ei_employee'),
            'ei_employer': safe_sum(remittances, 'ei_employer'),
            'cpp_employee': safe_sum(remittances, 'cpp_employee'),
            'cpp2_employee': safe_sum(remittances, 'cpp2_employee'),
            'cpp_employer': safe_sum(remittances, 'cpp_employer'),
            'cpp2_employer': safe_sum(remittances, 'cpp2_employer'),
        }
        
        lines = []
        grand_total = {'amount': 0, 'paid': 0, 'owed': 0}
        
        # Federal Taxes header
        lines.append({
            'id': 'federal_header',
            'name': _('Federal Taxes'),
            'values': {
                'tax_type': _('Federal Taxes'),
                'tax_amount': '',
                'tax_paid': '',
                'tax_owed': '',
            },
            'level': -1,
            'class': 'fw-bold',
        })
        
        for key, data in tax_totals.items():
            paid = paid_totals.get(key, 0)
            owed = data['amount'] - paid
            
            grand_total['amount'] += data['amount']
            grand_total['paid'] += paid
            grand_total['owed'] += owed
            
            lines.append({
                'id': f'tax_{key}',
                'name': data['name'],
                'values': {
                    'tax_type': f"  {data['name']}",
                    'tax_amount': data['amount'],
                    'tax_paid': paid,
                    'tax_owed': owed,
                },
                'level': 0,
            })
        
        # Grand total
        lines.append({
            'id': 'grand_total',
            'name': _('Total'),
            'values': {
                'tax_type': _('Total'),
                'tax_amount': grand_total['amount'],
                'tax_paid': grand_total['paid'],
                'tax_owed': grand_total['owed'],
            },
            'level': -1,
            'class': 'o_payroll_report_total fw-bold',
        })
        
        return lines


class PayrollReportTaxPayments(models.AbstractModel):
    """
    Payroll Tax Payments Report
    Shows history of tax remittance payments.
    """
    _name = 'payroll.report.tax.payments'
    _inherit = 'payroll.report'
    _description = 'Payroll Tax Payments Report'

    report_name = 'Payroll Tax Payments'
    report_code = 'tax_payments'
    filter_employee = False

    def _get_columns(self):
        return [
            {'name': _('Payment Date'), 'field': 'payment_date', 'type': 'date', 'sortable': True},
            {'name': _('Tax Type'), 'field': 'tax_type', 'type': 'char', 'sortable': True},
            {'name': _('Amount'), 'field': 'amount', 'type': 'monetary', 'sortable': True},
            {'name': _('Payment Method'), 'field': 'payment_method', 'type': 'char', 'sortable': False},
            {'name': _('Notes'), 'field': 'notes', 'type': 'char', 'sortable': False},
        ]

    def _get_lines(self, options):
        date_from = options.get('date', {}).get('date_from')
        date_to = options.get('date', {}).get('date_to')
        
        domain = [
            ('state', '=', 'paid'),
            ('company_id', '=', self.env.company.id),
        ]
        if date_from:
            domain.append(('payment_date', '>=', date_from))
        if date_to:
            domain.append(('payment_date', '<=', date_to))
        
        remittances = self.env['hr.tax.remittance'].search(domain, order='payment_date desc')
        
        lines = []
        for rem in remittances:
            period_start = getattr(rem, 'period_start', '') or ''
            period_end = getattr(rem, 'period_end', '') or ''
            period_str = f"{period_start} - {period_end}" if period_start and period_end else ''
            
            lines.append({
                'id': f'remit_{rem.id}',
                'name': rem.name or 'Unknown',
                'values': {
                    'payment_date': getattr(rem, 'payment_date', '') or '',
                    'tax_type': f"Federal Taxes\n{period_str}" if period_str else 'Federal Taxes',
                    'amount': getattr(rem, 'total', 0) or 0,
                    'payment_method': getattr(rem, 'payment_method', None) or 'Manual',
                    'notes': getattr(rem, 'payment_reference', None) or '',
                },
                'level': 0,
                'model': 'hr.tax.remittance',
                'res_id': rem.id,
            })
        
        return lines


class PayrollReportTaxWageSummary(models.AbstractModel):
    """
    Payroll Tax and Wage Summary Report
    Shows total wages, excess wages, taxable wages, and tax amounts.
    """
    _name = 'payroll.report.tax.wage.summary'
    _inherit = 'payroll.report'
    _description = 'Payroll Tax and Wage Summary Report'

    report_name = 'Payroll Tax and Wage Summary'
    report_code = 'tax_wage_summary'
    filter_employee = False

    def _get_columns(self):
        return [
            {'name': _('Tax Type'), 'field': 'tax_type', 'type': 'char', 'sortable': True},
            {'name': _('Total Wages'), 'field': 'total_wages', 'type': 'monetary', 'sortable': True},
            {'name': _('Excess Wages'), 'field': 'excess_wages', 'type': 'monetary', 'sortable': True},
            {'name': _('Taxable Wages'), 'field': 'taxable_wages', 'type': 'monetary', 'sortable': True},
            {'name': _('Tax Amount'), 'field': 'tax_amount', 'type': 'monetary', 'sortable': True},
        ]

    def _get_lines(self, options):
        date_from = options.get('date', {}).get('date_from')
        date_to = options.get('date', {}).get('date_to')
        
        domain = [
            ('state', 'in', ['done', 'paid']),
            ('company_id', '=', self.env.company.id),
        ]
        if date_from:
            domain.append(('date_from', '>=', date_from))
        if date_to:
            domain.append(('date_to', '<=', date_to))
        
        payslips = self.env['hr.payslip'].search(domain)
        
        # Calculate totals - safely handle missing gross_wage field
        total_wages = 0
        for slip in payslips:
            total_wages += getattr(slip, 'gross_wage', 0) or 0
        
        # Tax calculations
        tax_data = [
            {
                'name': _('Income Tax'),
                'codes': ['FED_TAX', 'PROV_TAX'],
                'total_wages': total_wages,
                'excess_wages': 0,  # No excess for income tax
            },
            {
                'name': _('Employment Insurance'),
                'codes': ['EI'],
                'total_wages': total_wages,
                'excess_wages': 0,  # Would need to calculate based on max
            },
            {
                'name': _('Employment Insurance Employer'),
                'codes': ['EI_ER'],
                'total_wages': total_wages,
                'excess_wages': 0,
            },
            {
                'name': _('Canada Pension Plan'),
                'codes': ['CPP'],
                'total_wages': total_wages,
                'excess_wages': 0,
            },
            {
                'name': _('Canada Pension Plan Employer'),
                'codes': ['CPP_ER'],
                'total_wages': total_wages,
                'excess_wages': 0,
            },
            {
                'name': _('Second Canada Pension Plan'),
                'codes': ['CPP2'],
                'total_wages': total_wages,
                'excess_wages': 0,
            },
            {
                'name': _('Second Canada Pension Plan Employer'),
                'codes': ['CPP2_ER'],
                'total_wages': total_wages,
                'excess_wages': 0,
            },
        ]
        
        lines = []
        
        # Federal header
        lines.append({
            'id': 'federal_header',
            'name': _('Federal Taxes'),
            'values': {
                'tax_type': _('Federal Taxes'),
                'total_wages': '',
                'excess_wages': '',
                'taxable_wages': '',
                'tax_amount': '',
            },
            'level': -1,
            'class': 'fw-bold',
        })
        
        grand_tax = 0
        for data in tax_data:
            tax_amount = 0
            for slip in payslips:
                if not hasattr(slip, 'line_ids') or not slip.line_ids:
                    continue
                for line in slip.line_ids:
                    if not hasattr(line, 'code') or not line.code:
                        continue
                    if line.code in data['codes']:
                        tax_amount += abs(line.total or 0)
            
            taxable = data['total_wages'] - data['excess_wages']
            grand_tax += tax_amount
            
            lines.append({
                'id': f"tax_{data['name']}",
                'name': data['name'],
                'values': {
                    'tax_type': f"  {data['name']}",
                    'total_wages': data['total_wages'],
                    'excess_wages': data['excess_wages'],
                    'taxable_wages': taxable,
                    'tax_amount': tax_amount,
                },
                'level': 0,
            })
        
        return lines
