# -*- coding: utf-8 -*-
"""
Paycheque Reports
=================
- Paycheque History
- Payroll Details
"""

from odoo import api, fields, models, _


class PayrollReportPaychequeHistory(models.AbstractModel):
    """
    Paycheque History Report
    Shows all paycheques with pay date, employee, amounts, payment method.
    """
    _name = 'payroll.report.paycheque.history'
    _inherit = 'payroll.report'
    _description = 'Paycheque History Report'

    report_name = 'Paycheque History'
    report_code = 'paycheque_history'

    def _get_columns(self):
        return [
            {'name': _('Pay Date'), 'field': 'pay_date', 'type': 'date', 'sortable': True},
            {'name': _('Name'), 'field': 'name', 'type': 'char', 'sortable': True},
            {'name': _('Total Pay'), 'field': 'total_pay', 'type': 'monetary', 'sortable': True},
            {'name': _('Net Pay'), 'field': 'net_pay', 'type': 'monetary', 'sortable': True},
            {'name': _('Pay Method'), 'field': 'pay_method', 'type': 'char', 'sortable': True},
            {'name': _('Cheque Number'), 'field': 'cheque_number', 'type': 'char', 'sortable': False},
            {'name': _('Status'), 'field': 'status', 'type': 'char', 'sortable': True},
        ]

    def _get_lines(self, options):
        domain = self._get_domain(options)
        domain.append(('state', 'in', ['done', 'paid']))
        
        payslips = self.env['hr.payslip'].search(domain, order='date_to desc, employee_id')
        
        lines = []
        for slip in payslips:
            if not slip.employee_id:
                continue
                
            pay_method = '-'
            if hasattr(slip, 'paid_by') and slip.paid_by:
                if 'paid_by' in slip._fields and hasattr(slip._fields['paid_by'], 'selection'):
                    pay_method = dict(slip._fields['paid_by'].selection).get(slip.paid_by, '-')
            
            status = slip.state
            if 'state' in slip._fields and hasattr(slip._fields['state'], 'selection'):
                status = dict(slip._fields['state'].selection).get(slip.state, slip.state)
            
            lines.append({
                'id': f'payslip_{slip.id}',
                'name': slip.employee_id.name or 'Unknown',
                'values': {
                    'pay_date': slip.date_to or '',
                    'name': slip.employee_id.name or 'Unknown',
                    'total_pay': slip.gross_wage or 0,
                    'net_pay': slip.net_wage or 0,
                    'pay_method': pay_method,
                    'cheque_number': getattr(slip, 'cheque_number', None) or '-',
                    'status': status,
                },
                'level': 0,
                'model': 'hr.payslip',
                'res_id': slip.id,
            })
        
        # Add total
        if lines:
            lines.append(self._get_total_line(lines, options))
        
        return lines


class PayrollReportPayrollDetails(models.AbstractModel):
    """
    Payroll Details Report
    Detailed breakdown per employee per pay date with Gross, Taxes, Net.
    """
    _name = 'payroll.report.payroll.details'
    _inherit = 'payroll.report'
    _description = 'Payroll Details Report'

    report_name = 'Payroll Details'
    report_code = 'payroll_details'

    def _get_columns(self):
        return [
            {'name': _('Pay Date'), 'field': 'pay_date', 'type': 'date', 'sortable': True},
            {'name': _('Name'), 'field': 'name', 'type': 'char', 'sortable': True},
            {'name': _('Hours'), 'field': 'hours', 'type': 'float', 'sortable': True},
            {'name': _('Gross Pay'), 'field': 'gross_pay', 'type': 'monetary', 'sortable': True},
            {'name': _('Other Pay'), 'field': 'other_pay', 'type': 'monetary', 'sortable': False},
            {'name': _('Employee Taxes'), 'field': 'employee_taxes', 'type': 'monetary', 'sortable': True},
            {'name': _('Net Pay'), 'field': 'net_pay', 'type': 'monetary', 'sortable': True},
        ]

    def _get_lines(self, options):
        domain = self._get_domain(options)
        domain.append(('state', 'in', ['done', 'paid']))
        
        payslips = self.env['hr.payslip'].search(domain, order='date_to desc, employee_id')
        
        lines = []
        
        # Group by pay date for totals
        current_date = None
        date_totals = {'gross_pay': 0, 'employee_taxes': 0, 'net_pay': 0, 'hours': 0}
        
        # Calculate grand totals
        grand_totals = {'gross_pay': 0, 'employee_taxes': 0, 'net_pay': 0, 'hours': 0}
        
        for slip in payslips:
            if not slip.employee_id:
                continue
            
            # Calculate worked hours
            hours = 0
            if hasattr(slip, 'worked_days_line_ids') and slip.worked_days_line_ids:
                hours = sum(slip.worked_days_line_ids.mapped('number_of_hours')) or 0
            
            # Calculate employee taxes
            employee_taxes = getattr(slip, 'total_employee_deductions', 0) or 0
            gross_wage = getattr(slip, 'gross_wage', 0) or 0
            net_wage = getattr(slip, 'net_wage', 0) or 0
            
            grand_totals['gross_pay'] += gross_wage
            grand_totals['employee_taxes'] += employee_taxes
            grand_totals['net_pay'] += net_wage
            grand_totals['hours'] += hours
            
            lines.append({
                'id': f'detail_{slip.id}',
                'name': slip.employee_id.name or 'Unknown',
                'values': {
                    'pay_date': slip.date_to or '',
                    'name': slip.employee_id.name or 'Unknown',
                    'hours': hours,
                    'gross_pay': gross_wage,
                    'other_pay': 0,  # Can be calculated from specific line types
                    'employee_taxes': employee_taxes,
                    'net_pay': net_wage,
                },
                'level': 0,
                'model': 'hr.payslip',
                'res_id': slip.id,
                'unfoldable': True,  # Can expand to show breakdown
            })
        
        # Add grand total
        if lines:
            lines.append({
                'id': 'grand_total',
                'name': _('Total'),
                'values': {
                    'pay_date': '',
                    'name': _('Total'),
                    'hours': grand_totals['hours'],
                    'gross_pay': grand_totals['gross_pay'],
                    'other_pay': 0,
                    'employee_taxes': grand_totals['employee_taxes'],
                    'net_pay': grand_totals['net_pay'],
                },
                'level': -1,
                'class': 'o_payroll_report_total fw-bold',
            })
        
        return lines

    def _get_detail_lines(self, payslip_id, options):
        """Get expanded detail lines for a payslip."""
        try:
            payslip = self.env['hr.payslip'].browse(payslip_id)
            if not payslip.exists():
                return []
            
            lines = []
            
            if not hasattr(payslip, 'line_ids') or not payslip.line_ids:
                return lines
            
            # Gross breakdown
            gross_lines = payslip.line_ids.filtered(
                lambda l: hasattr(l, 'category_id') and l.category_id and 
                         hasattr(l.category_id, 'code') and 
                         l.category_id.code in ['BASIC', 'ALW', 'GROSS']
            )
            for line in gross_lines:
                lines.append({
                    'id': f'line_{line.id}',
                    'name': line.name or '',
                    'values': {
                        'pay_date': '',
                        'name': f'  {line.name or ""}',
                        'hours': line.quantity if hasattr(line, 'quantity') and line.quantity else '',
                        'gross_pay': line.total or 0,
                        'other_pay': '',
                        'employee_taxes': '',
                        'net_pay': '',
                    },
                    'level': 1,
                    'class': 'text-muted',
                })
            
            # Tax breakdown
            tax_lines = payslip.line_ids.filtered(
                lambda l: hasattr(l, 'code') and l.code in ['CPP', 'CPP2', 'EI', 'FED_TAX', 'PROV_TAX']
            )
            for line in tax_lines:
                lines.append({
                    'id': f'tax_{line.id}',
                    'name': line.name or '',
                    'values': {
                        'pay_date': '',
                        'name': f'  {line.name or ""}',
                        'hours': '',
                        'gross_pay': '',
                        'other_pay': '',
                        'employee_taxes': abs(line.total or 0),
                        'net_pay': '',
                    },
                    'level': 1,
                    'class': 'text-muted',
                })
            
            return lines
        except Exception:
            return []
