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


class sos_sales_action_plan(models.Model):
    _name = 'sos_sales_action_plan'
    _description = 'Sosaley Sales Action Plan'
    _rec_name="customer_name"

    date = fields.Date(string="Action Date",required=True)
    customer_name = fields.Many2one(
        'sos_customers', 
        string="Customer Name", 
        required=True,
        domain=lambda self: self._get_customer_domain()
    )
    end_customer_name = fields.Char(string="End Customer Name")
    quote_no = fields.Char(string="Quote/W.O No",help="Fill this if the same customer has different work orders.")
    quote_no_selector = fields.Many2one(
        'sos_case_diary',
        string="End Customer/Quote No",
        domain="[('customer_name', '=', customer_name), ('quote_no', '!=', False)]"
    )
    ce_product_type = fields.Selection(
            [
                ('Sales', 'Sales'), 
                ('Service', 'Service'), 
                ('Spare', 'Spare'),  
                ('Cloud', 'Cloud')                   
            ],
            string="Service Type")
    product = fields.Selection(
            [
               ('BHMS 1.2V', 'BHMS 1.2V'), 
                ('BHMS 2V', 'BHMS 2V'), 
                ('BHMS 12V', 'BHMS 12V'),  
                ('BHMS 48V', 'BHMS 48V'),
                ('BMS-HV', 'BMS-HV'),
                ('BMS-LV 100A', 'BMS-LV 100A'), 
                ('BMS-LV 40A', 'BMS-LV 40A'), 
                ('SBMS 55A', 'SBMS 55A'),              
                ('MC 250W', 'MC 250W'),                                
                ('HeartTarang', 'HeartTarang')                
            ],
            string="Products",required=True)
    location = fields.Char(string="Location")
    quantity = fields.Char(string="Quantity")
    sales_executive = fields.Many2one(
        'res.users', 
        string='Sales Executive', 
        default=lambda self: self.env.user,
        readonly=True
    )
    sales_head = fields.Many2one(
        'res.users', 
        string='Sales Head',
        default=lambda self: self.env.user,
        domain=lambda self: [('groups_id', 'in', self.env.ref('sos_inventory.sos_sales_user').ids + self.env.ref('sos_inventory.sos_ce_head').ids)]

    )
    action_type = fields.Selection([
        ('Meeting', 'Meeting'),
        ('Demo', 'Demo'),
        ('Discussion', 'Discussion'),
        ('Visit', 'Direct Visit'),
        ('Negotiation', 'Negotiation'),
        ('Validation', 'Validation'),
        ('Proposal', 'Proposal'),
        ('Email/Call/Video Call', 'Email/Call/Video Call')
    ], string='Action Type',requierd=True)
    current_spenco_status = fields.Selection([
        ('Suspects', 'Suspects'),
        ('Prospects', 'Prospects'),
        ('Engaged', 'Engaged'),
        ('Negotiation', 'Negotiation'),
        ('Commercial Order', 'Commercial Order')
    ], string='Current SPENCO Status')
    po_copy = fields.Binary(string='PO Copy', attachment=True)
    po_copy_filename = fields.Char(string='PO Copy Filename')
    action = fields.Selection(
            [
                ('Generate More Suspects', 'Generate More Suspects'), 
                ('Suspect to Prospects', 'Suspect to Prospects'), 
                ('Prospect to Engaged', 'Prospect to Engaged'),  
                ('Engaged to Negotiation', 'Engaged to Negotiation'),
                ('Negotiation to Order', 'Negotiation to Order')        
            ],
            string="Action Category",required=True)
    action_plan = fields.Text(string="Action Plan")
    result = fields.Text(string="Result")
    status = fields.Selection(
            [
                ('open', 'Open'), 
                ('close', 'Closed without Order'),
                ('close_order', 'Closed with Order') 
            ],
            string="Status",default='open',required=True)
    currency_id = fields.Many2one('res.currency', string='Currency')
    po_no= fields.Char(string="PO No")
    value = fields.Monetary(currency_field='currency_id', string="Value (In Lakhs)")
    next_action_date = fields.Date(string="Next Action On")
    update_done = fields.Boolean(string="Update Done", default=False)
    state = fields.Selection([
        ('draft', 'Draft'),
        ('confirmed', 'Confirmed'),
    ], string='State', default='draft', readonly=True)

    def _get_customer_domain(self):
        if (
            self.env.user.has_group('sos_inventory.sos_management_user') or
            self.env.user.has_group('sos_inventory.sos_ce_head') or
            self.env.user.has_group('sos_inventory.sos_ce_user')
        ):
            return []  # no filter, show all
        return [('responsible', '=', self.env.uid)]


    @api.onchange('quote_no_selector')
    def _onchange_quote_no_selector(self):
        if self.quote_no_selector:
            self.quote_no = self.quote_no_selector.quote_no
            self.end_customer_name = self.quote_no_selector.end_customer_name

    def action_prev_action_plans(self):
        domain = [('customer_name', '=', self.customer_name.id)]
        if self.quote_no:
            domain.append(('quote_no', '=', self.quote_no))
        if self.quote_no:
            domain.append(('product', '=', self.product))
        prev_action_plans = self.env['sos_sales_action_plan'].search(domain)
        return {
            'type': 'ir.actions.act_window',
            'name': 'Previous Action Plans',
            'res_model': 'sos_sales_action_plan',
            'view_mode': 'tree',
            'views': [(self.env.ref('sos_sales.view_prev_action_plan_tree').id, 'tree')],
            'domain': [('id', 'in', prev_action_plans.ids)],
            'target': 'new',
        }
    @api.onchange('quote_no')
    def _onchange_quote_no(self):
        """Set products from sos_case_diary if quote_no and customer match"""
        if self.customer_name and self.quote_no:
            case = self.env['sos_case_diary'].search([
                ('customer_name', '=', self.customer_name.id),
                ('quote_no', '=', self.quote_no)
            ], limit=1)

            if case:
                self.product = case.products  # assuming it's Char or same type
                self.location = case.customer_city
                self.quantity = case.quantity
            else:
                self.product = False
                self.location = False
                self.quantity = False
    def write(self, vals):
        if 'status' in vals:
            for record in self:
                domain = [
                    ('customer_name', '=', record.customer_name.customer_name),
                    ('products', '=', record.product),
                    ('sales_person', '=', record.sales_executive.id)
                ]
                if record.quote_no:
                    domain.append(('quote_no', '=', record.quote_no))

                case_diary_records = self.env['sos_case_diary'].search(domain, limit=1)
                if case_diary_records:
                    case_diary_records.write({"status": vals['status']})

        return super().write(vals)


    def action_view_po(self):
        # Check if there is a test report
        if not self.po_copy:
            raise UserError("No po available for this record.")
        
        # Use `ir.actions.act_url` to open the binary file as a PDF
        return {
        'type': 'ir.actions.act_url',
        'url': '/web/content/{}/{}/{}?download=false'.format(
            self._name, self.id, 'po_copy'),
        'target': 'new',  # This opens the PDF in a new tab
        }
    @api.onchange('current_spenco_status')
    def _onchange_current_spenco_status(self):
        if self.current_spenco_status != 'Commercial Order':
            self.po_copy = False

    def unlink(self):
        for record in self:
            if record.update_done:
                raise UserError("You can't delete the action plan after case diary updation!")

            action_plan_date = record.date
            sales_executive = record.sales_executive

            # Week-wise
            week_number = record._compute_week_number(action_plan_date)
            record.decrement_summary(
                action_plan_date=action_plan_date,
                sales_executive=sales_executive,
                field_name='week_number',
                field_value=week_number,
                model_name='sos_action_plan_summary_week_wise'
            )
            # Month-wise
            month_number = record._compute_month_number(action_plan_date)
            record.decrement_summary(
                action_plan_date=action_plan_date,
                sales_executive=sales_executive,
                field_name='month_number',
                field_value=month_number,
                model_name='sos_action_plan_summary_month_wise'
            )
            # Quarter-wise
            quarter_number = record._compute_quarter_number(action_plan_date)
            record.decrement_summary(
                action_plan_date=action_plan_date,
                sales_executive=sales_executive,
                field_name='quarter_number',
                field_value=quarter_number,
                model_name='sos_action_plan_summary_quarter_wise'
            )
            # Year-wise
            year_number = record._compute_year_number(action_plan_date)
            record.decrement_summary(
                action_plan_date=action_plan_date,
                sales_executive=sales_executive,
                field_name='year',
                field_value=year_number,
                model_name='sos_action_plan_summary_year_wise'
            )

        return super(sos_sales_action_plan, self).unlink()

    def decrement_summary(self, action_plan_date, sales_executive, field_name, field_value, model_name):
        SummaryModel = self.env[model_name]

        record = SummaryModel.search([
            ('sales_executive', '=', sales_executive.id),
            (field_name, '=', field_value),
            ('action', '=', self.action),
            ('action_type', '=', self.action_type)
        ], limit=1)

        if record and record.count > 1:
            record.write({'count': record.count - 1})
        elif record:
            record.unlink()

    @api.model
    def create(self, vals):
        record = super(sos_sales_action_plan, self).create(vals)
        record.state = 'confirmed'

        # Now access fields from the created record
        sales_executive = record.sales_executive
        action_plan_date = record.date
        #week wise
        week_number = record._compute_week_number(action_plan_date)
        record.update_summary(
            action_plan_date=action_plan_date,
            sales_executive=sales_executive,
            field_name='week_number',
            field_value=week_number,
            model_name='sos_action_plan_summary_week_wise'
        )
        #month wise
        month_number = record._compute_month_number(action_plan_date)
        record.update_summary(
            action_plan_date=action_plan_date,
            sales_executive=sales_executive,
            field_name='month_number',
            field_value=month_number,
            model_name='sos_action_plan_summary_month_wise'
        )
        #quarter wise
        quarter_number = record._compute_quarter_number(action_plan_date)
        record.update_summary(
            action_plan_date=action_plan_date,
            sales_executive=sales_executive,
            field_name='quarter_number',
            field_value=quarter_number,
            model_name='sos_action_plan_summary_quarter_wise'
        )
        #year wise
        year_number = record._compute_year_number(action_plan_date)
        record.update_summary(
            action_plan_date=action_plan_date,
            sales_executive=sales_executive,
            field_name='year',
            field_value=year_number,
            model_name='sos_action_plan_summary_year_wise'
        )
        return record
    def _compute_year_number(self,action_plan_date):
        month_number = action_plan_date.strftime('%B')
        month = action_plan_date.month
        year = action_plan_date.year
        year_number = f"{year}-{year + 1}" if month >= 4 else f"{year - 1}-{year}"
        return year_number
    def _compute_quarter_number(self,action_plan_date):
        month_number = action_plan_date.strftime('%B')
        month = action_plan_date.month
        quarter_number = (
            "Q1" if 4 <= month <= 6 else
            "Q2" if 7 <= month <= 9 else
            "Q3" if 10 <= month <= 12 else "Q4"
        )
        return quarter_number
    def _compute_month_number(self,action_plan_date):
        month_number = action_plan_date.strftime('%B')
        return month_number
    def _compute_week_number(self,action_plan_date):
        start_of_week = action_plan_date - timedelta(days=action_plan_date.weekday())
        end_of_week = start_of_week + timedelta(days=5)
        return f"{start_of_week.strftime('%b %d')} - {end_of_week.strftime('%b %d')}"
    def update_summary(self, action_plan_date, sales_executive, field_name, field_value, model_name):
        SummaryModel = self.env[model_name]
        
        record = SummaryModel.search([
            ('sales_executive', '=', sales_executive.id),
            (field_name, '=', field_value),
            ('action', '=', self.action),
            ('action_type', '=', self.action_type)
        ], limit=1)

        if record:
            record.write({
                'count': record.count + 1
            })
        else:
            record = SummaryModel.create({
                'sales_executive': sales_executive.id,
                field_name: field_value,
                'action': self.action,
                'action_type': self.action_type,
                'entered_date': action_plan_date,
                'count': 1
            })

        return record

    def view_casediary(self):
        domain = [
            ('customer_name', '=', self.customer_name.id),
            ('products', '=', self.product),
            ('sales_person', '=', self.sales_executive.id)
        ]
        if self.quote_no:
            domain.append(('quote_no', '=', self.quote_no))
        case_diary_records = self.env['sos_case_diary'].search(domain, limit=1)
        if case_diary_records:
            return {
            'type': 'ir.actions.act_window',
            'name': 'Case Diary',
            'res_model': 'sos_case_diary',
            'view_mode': 'form',
            'res_id': case_diary_records.id,
            'target': 'current',
        }
        else:
            return {
                    'type': 'ir.actions.client',
                    'tag': 'display_notification',
                    'params': {
                        'message': "Not Found",
                        'type': 'danger',
                        'sticky': False
                    }
                }



    def update_casediary(self):
        if self.update_done:
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'message': "Already updated!",
                    'type': 'warning',
                    'sticky': False
                }
            }

        # Validate mandatory fields
        missing_fields = []
        if not self.current_spenco_status:
            missing_fields.append("Current SPENCO Status")
        if not self.next_action_date:
            missing_fields.append("Next Action Date")
        if not self.result:
            missing_fields.append("Result")
        if self.value <= 0.00:
            if self.current_spenco_status != "Suspects":
                missing_fields.append("Value")

        if missing_fields:
            raise UserError(
                f"The following fields are required before updating the Case Diary: {', '.join(missing_fields)}"
            )

        self.update_done = True

        domain = [
            ('customer_name', '=', self.customer_name.id),
            ('products', '=', self.product),
            ('sales_person', '=', self.env.user.id)
        ]

        if self.quote_no:
            domain.append(('quote_no', '=', self.quote_no))
        if self.end_customer_name:
            domain.append(('end_customer_name', '=', self.end_customer_name))
        case_diary_records = self.env['sos_case_diary'].search(domain, limit=1)

        if case_diary_records:
            case_diary_records.write({
                'status': self.status,
                'po_copy':self.po_copy,
                'po_no':self.po_no,
                'quantity':self.quantity,
                'po_copy_filename':self.po_copy_filename
            })
            case_diary_records.line_ids.create({
                'ref_id': case_diary_records.id,
                'action_plan_date': self.date,
                'action_plan': self.action_plan,
                'action_type': self.action_type,
                'notes': self.result,
                'next_action_date': self.next_action_date,
                'status_changed_on': date.today(),
                'spenco_status': self.current_spenco_status,
                'current_state_value': self.value,
            })
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'message': "Updated",
                    'type': 'success',
                    'sticky': False
                }
            }
        else:
            vals = {
                'customer_name': self.customer_name.id,
                'end_customer_name': self.end_customer_name,
                'customer_city': self.location,
                'sales_person': self.sales_executive.id,
                'products': self.product,
                'proposal_value': self.value,
                'status': self.status,
                'quote_no': self.quote_no,
                'quantity': self.quantity,
                'po_no': self.po_no,
                'po_copy': self.po_copy,
                'po_copy_filename': self.po_copy_filename
            }
            if self.ce_product_type:
                vals['ce_product_type'] = self.ce_product_type
            casediary_record = self.env['sos_case_diary'].create(vals)
            self.env['sos_case_diary_line'].create({
                'ref_id': casediary_record.id,
                'action_plan_date': self.date,
                'action_plan': self.action_plan,
                'action_type': self.action_type,
                'notes': self.result,
                'next_action_date': self.next_action_date,
                'status_changed_on': date.today(),
                'spenco_status': self.current_spenco_status,
                'current_state_value': self.value
            })
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'message': "Created New Case Diary",
                    'type': 'success',
                    'sticky': False
                }
            }
