from odoo import models, api
from odoo.exceptions import UserError
from datetime import date, timedelta
from calendar import month_name

class WeekSummaryReport(models.AbstractModel):
    _name = 'report.sos_sales.report_week_summary'
    _description = 'Weekly Summary Report'

    def compute_aggregated_data(self, model_name, domain, status_map):
        records = self.env[model_name].search(domain)
        result = {
            'Opening': {'P': {'count': 0, 'value': 0.0}, 'E': {'count': 0, 'value': 0.0}, 'N': {'count': 0, 'value': 0.0}, 'CO': {'count': 0, 'value': 0.0}, 'EOV': {'count': 0,'value': 0.0}},
            'Downgrade': {'P': {'count': 0, 'value': 0.0}, 'E': {'count': 0, 'value': 0.0}, 'N': {'count': 0, 'value': 0.0}, 'CO': {'count': 0, 'value': 0.0}, 'EOV': {'count': 0,'value': 0.0}},
            'Upgrade': {'P': {'count': 0, 'value': 0.0}, 'E': {'count': 0, 'value': 0.0}, 'N': {'count': 0, 'value': 0.0}, 'CO': {'count': 0, 'value': 0.0}, 'EOV': {'count': 0,'value': 0.0}},
            'New': {'P': {'count': 0, 'value': 0.0}, 'E': {'count': 0, 'value': 0.0}, 'N': {'count': 0, 'value': 0.0}, 'CO': {'count': 0, 'value': 0.0}, 'EOV': {'count': 0,'value': 0.0}},
            'Closing': {'P': {'count': 0, 'value': 0.0}, 'E': {'count': 0, 'value': 0.0}, 'N': {'count': 0, 'value': 0.0}, 'CO': {'count': 0, 'value': 0.0}, 'EOV': {'count': 0,'value': 0.0}},
        }

        for rec in records:
            status = rec.spenco_status
            if status not in status_map:
                continue
            key = status_map[status]
            for stage in ['Opening', 'Downgrade', 'Upgrade', 'New']:
                count = getattr(rec, f'{stage.lower()}_cases_count', 0) or 0
                value = getattr(rec, f'{stage.lower()}_cases_value', 0.0) or 0.0
                result[stage][key]['count'] += count
                result[stage][key]['value'] += value
                result[stage]['EOV']['count'] += count
                result[stage]['EOV']['value'] += value

        for key in ['P', 'E', 'N', 'CO','EOV']:
            result['Closing'][key]['count'] = (
                result['Opening'][key]['count'] -
                result['Downgrade'][key]['count'] -
                result['Upgrade'][key]['count'] +
                result['New'][key]['count']
            )
            result['Closing'][key]['value'] = round(
                result['Opening'][key]['value'] -
                result['Downgrade'][key]['value'] -
                result['Upgrade'][key]['value'] +
                result['New'][key]['value'],
                2
            )
        return result

    @api.model
    def _get_report_values(self, docids, data=None):
        # Validate input data
        if not data:
            raise UserError("No filter data provided for the report.")
        
        sales_person_id = data.get('sales_person_id')
        week_number = data.get('week_number')

        # Calculate week range
        current_date = date.today()
        start_of_week = current_date - timedelta(days=current_date.weekday())
        end_of_week = start_of_week + timedelta(days=5)
        # Calculate month range
        month_number = current_date.strftime('%B')
        # Calculate quarter range
        month = current_date.month
        year = current_date.year
        if 4 <= month <= 6:
            quarter_number = "Q1"
        elif 7 <= month <= 9:
            quarter_number = "Q2"
        elif 10 <= month <= 12:
            quarter_number = "Q3"
        else:  
            quarter_number = "Q4"
        # Calculate year range
        if month >= 4:
            year_number = f"{year}-{year + 1}"
        else:
            year_number = f"{year - 1}-{year}"

        sales_person_name = self.env['res.users'].browse(sales_person_id).name if sales_person_id else 'All Sales Persons'

        # Build domain
        domain = [('week_number', '=', week_number)]
        if sales_person_id:
            domain.append(('sales_executive', '=', sales_person_id))

        

        # Aggregate data by stage and spenco_status
        status_map = {
            'Prospects': 'P',
            'Engaged': 'E',
            'Negotiation': 'N',
            'Commercial Order': 'CO'
        }
        #week wise start
        def build_domain(field_name, value):
            domain = [(field_name, '=', value)]
            if sales_person_id:
                domain.append(('sales_executive', '=', sales_person_id))
            return domain

        aggregated_data_week = self.compute_aggregated_data(
            'sos_spenco_summary_week_wise',
            build_domain('week_number', week_number),
            status_map
        )
        aggregated_data_month = self.compute_aggregated_data(
            'sos_spenco_summary_month_wise',
            build_domain('month_number', month_number),
            status_map
        )
        aggregated_data_quarter = self.compute_aggregated_data(
            'sos_spenco_summary_quarter_wise',
            build_domain('quarter_number', quarter_number),
            status_map
        )
        aggregated_data_year = self.compute_aggregated_data(
            'sos_spenco_summary_year_wise',
            build_domain('year', year_number),
            status_map
        )

        
        # Return values for the report template
        return {
            'doc_ids': docids or [],
            'doc_model': 'sos_spenco_summary_week_wise',
            'aggregated_data': aggregated_data_week,
            'aggregated_data_month': aggregated_data_month,
            'aggregated_data_quarter': aggregated_data_quarter,
            'aggregated_data_year':aggregated_data_year,
            'week_number': week_number,
            'month_number':month_number,
            'quarter_number':quarter_number,
            'year_number':year_number,
            'sales_person_name': sales_person_name
        }
