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

class FIR_BRR(models.Model):
    _name = 'sos_fir_brr'
    _description = 'Batch Release Report'
    _rec_name='fir_no'
    _order = 'id desc'

    fir_no = fields.Char(string="BRR No",default=lambda self: self._generate_id(),readonly= True, required= True)
    fir_date = fields.Date(string="BRR Date")
    fg_name = fields.Many2one('sos_fg', string='FG Name')
    product_name = fields.Char(related="fg_name.name", string='Product Name',readonly=True)
    plan_ref_no = fields.Many2one('sos_fg_plan', string='Indent Ref No')
    batch_size = fields.Integer(string="Batch Size / Received Quantity")
    batch_No = fields.Char(string="Batch No")
    mfg_date = fields.Char(string="Manufacturing Date")
    sampling_size = fields.Char(string="Sampling Size")
    serial_no_line_ids = fields.One2many('sos_brr_serial_no_lines', 'ref_id',copy=True)
    calibration_line_ids = fields.One2many('sos_calibration_devices_fir', 'ref_id',copy=True)
    testing_parameter_line_ids = fields.One2many('sos_fir_brr_line', 'ref_line_id',copy=True)
    approved_qty = fields.Integer(string="Approved Quantity")
    rejected_qty = fields.Integer(string="Rejected Quantity")
    rejection_percentage = fields.Float(string="Rejected Percentage", compute="_compute_rejected_percentage", store=True)
    rejection_percentage_display = fields.Char('Rejection Percentage', compute='_compute_rejected_percentage_display')
    qc_by_name = fields.Many2one('res.users', string='QC Tested&Provided by Sign')
    qc_by_image = fields.Image(related="qc_by_name.signature_image",string='Prepared by Sign',readonly=True)
    qc_tested_on = fields.Date(string="Approved On")
    reworked_count = fields.Integer(string="Reworked Count",default=0)
    qa_by_name = fields.Many2one('res.users', string='QA by Sign')
    qa_by_image = fields.Image(related="qa_by_name.signature_image",string='Prepared by Sign',readonly=True)
    qa_tested_on = fields.Datetime(string="Approved On")
    ppm = fields.Integer(string="PPM",compute="_compute_ppm")
    stores_received_by = fields.Many2one('res.users', string='Store Received by Sign')
    stores_received_image = fields.Image(related="stores_received_by.signature_image",string='Stores Received by Sign',readonly=True)
    stores_received_on = fields.Date(string="Stores Received On")
    ncmr_ref = fields.Many2one('sos_ncmr',string="NCMR Reference (If any Rejected)")
    def action_report_brr_btn(self):
        try:
            action = self.env.ref("sos_inventory.action_report_brr").report_action(self)
            return action
        except ValueError as e:
            print(f"Failed to find report action: {e}")
    @api.depends('batch_size', 'rejected_qty')
    def _compute_ppm(self):
        for record in self:
            if record.rejected_qty != 0:
                record.ppm = (record.rejected_qty / record.batch_size) * 10**6
            else:
                record.ppm = 0 
    @api.depends('rejection_percentage')
    def _compute_rejected_percentage_display(self):
        for record in self:
            record.rejection_percentage_display = "{:.2f}%".format(record.rejection_percentage)
    @api.depends('batch_size', 'rejected_qty')
    def _compute_rejected_percentage(self):
        for record in self:
            if record.batch_size > 0:
                record.rejection_percentage = (record.rejected_qty / record.batch_size) * 100
            else:
                record.rejection_percentage = 0
    def action_qc_esign_btn(self):          
        ncmr_record = False
        sequence_util = self.env['sos_common_scripts']
        ncmr_id = sequence_util.generate_sequence('sos_ncmr', 'NCMR', 'ncmr_no')
        if self.rejected_qty > 0:      
            ncmr_record = self.env['sos_ncmr'].create({
                        'ncmr_no': ncmr_id,
                        'fg_option':True,
                        'material_option':False,
                        'sfg_option':False,
                        'batch_no':self.batch_No,
                        'rejected_qty':self.rejected_qty,
                        'fg_name': self.fg_name.id,
                        'fg_incoming_doc_ref':self.id,
                        'department':'Quality Control'
                    })

        if ncmr_record:
            self.ncmr_ref = ncmr_record.id
            ncmr_body_html = f"""
                <p>Below <b>NCMR</b> is waiting for your Inspection</p>
                """
            sequence_util.send_group_email(self.env,'sos_ncmr',ncmr_id,"deenalaura.m@sosaley.in","NCMR Inspection Pending",ncmr_body_html,'sos_inventory.sos_qc_user')

        # Email part
        body_html = f"""
        <p>Below <b>Batch Release Report</b> is waiting for your Approval</p>
        """
        
        sequence_util.send_group_email(self.env,"sos_fir_brr",self.id,"deenalaura.m@sosaley.in","BRR Approval Request",body_html,'sos_inventory.sos_qa_user')

        # Email part ends
        return sequence_util.action_assign_signature(
        self, 
        'qc_by_name',
        'qc_tested_on'
    )
    def action_qa_esign_btn(self):
        # Email part
        body_html = f"""
        <p>Below <b>FIR</b> is waiting for your Approval</p>
        """
        
        send_email = self.env['sos_common_scripts']
        send_email.send_group_email(self.env,"sos_fir_brr",self.id,"deenalaura.m@sosaley.in","BRR Approval Request",body_html,'sos_inventory.sos_scg_group_user')
        # Email part ends
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.action_assign_signature(
        self, 
        'qa_by_name',
        'qa_tested_on'
    )
    def action_stores_esign_btn(self):
        if self.plan_ref_no:
            # Production Status
            sos_record = self.env['sos_production_plan'].search([
                            ('fg_name', '=', self.fg_name.id),
                            ('plan_ref_no', '=', self.plan_ref_no.plan_ref_no)
                        ], limit=1)
            sequence_util = self.env['sos_common_scripts']
            week_number = sequence_util.calculate_week_number(
            sos_record.indent_start_date , 
            sos_record.target_date , 
            date.today()
            )
            field_name = f'qc_week_{week_number}'
            fgplan_field_name = f'planned_week_{week_number}'
            # FG Plan update
            fg_plan_record = self.env['sos_fg_plan_line'].search([
                ('fg_name', '=', self.fg_name.id)
            ], limit=1)

            if fg_plan_record:
                current_value = getattr(fg_plan_record, fgplan_field_name, 0)
                fg_plan_record.write({fgplan_field_name: current_value + self.approved_qty}) 
            if sos_record:
                current_value = getattr(sos_record, field_name, 0)
                sos_record.write({field_name: current_value + self.approved_qty})
            # Production Status Ends  
        sequence_util = self.env['sos_common_scripts']
        sequence_util.action_assign_signature(
        self, 
        'stores_received_by',
        'stores_received_on',
        'sos_inventory.sos_scg_group_user'
    )
        approved_qty = self.approved_qty
        if approved_qty > 0:
            current_qty = self.fg_name.inhand_stock_qty
            new_qty = current_qty + approved_qty
            self.fg_name.inhand_stock_qty = new_qty
            self.env['sos_fg_transaction_history'].create({
                'ref_id': self.fg_name.id,
                'fir_no': self.id,
                'component_id': self.fg_name.id,
                'quantity': approved_qty,
                'action': 'in',
            })
        
    def _generate_id(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.generate_sequence('sos_fir_brr','BRR', 'fir_no')
    
    @api.onchange('fg_name')
    def _onchange_fg_name(self):
        if self.fg_name:
            self._load_testing_parameters()

    @api.model
    def create(self, vals):
        record = super(FIR_BRR, self).create(vals)
        if record.fg_name:
            record._load_testing_parameters()
        return record

    def write(self, vals):
        result = super(FIR_BRR, self).write(vals)
        if 'fg_name' in vals:
            self._load_testing_parameters()
        return result

    def _load_testing_parameters(self):
        if self.fg_name:
            testing_parameters = self.env['sos_testing_parameters'].search([('fg_name', '=', self.fg_name.id)])
            if not testing_parameters:
                raise UserError('No testing parameters found for this FG.')

            # Clear any existing lines
            lines = [(5, 0, 0)]

            sorted_parameters = testing_parameters.parameter_ids.sorted(key=lambda param: param.sequence)
            # Append the sorted parameters
            for param in sorted_parameters:
                lines.append((0, 0, {
                    'testing_parameter': param.id,
                    'sequence': param.sequence,
                    'specification': param.specification,
                    'results': param.results,
                    'inspection_decision':param.inspection_decision
                }))

            # Set the sorted lines to testing_parameter_line_ids
            self.testing_parameter_line_ids = lines


class FIR_BRR_Line(models.Model):
    _name = 'sos_fir_brr_line'
    _description = 'Batch Release Report Line Items'

    ref_line_id = fields.Many2one('sos_fir_brr',  ondelete="cascade")
    sequence = fields.Integer(string="sequence")
    testing_parameter = fields.Many2one('sos_parameter', string='Testing Parameter')
    sampled_qty = fields.Integer(string="Sampled Quantity")
    accepted_qty = fields.Integer(string="Accepted Quantity")
    rejected_qty = fields.Integer(string="Rejected Quantity")
    remarks = fields.Text(string="Remarks")
    inspection_decision = fields.Selection([('PASS','PASS'),('FAIL','FAIL')],string="Inspection Decision")
    specification = fields.Char(string="Specification")
    results = fields.Text(string="Results")

class Calibration_devices(models.Model):
    _name = 'sos_calibration_devices_fir'
    _description = 'Calibartion Devices List'
    
    ref_id = fields.Many2one('sos_fir_brr',  ondelete="cascade")
    calibration_device = fields.Many2one('sos_calibration_devices',string="Equipment Name", required=True)
    identification_No = fields.Char(string="Identification No",related="calibration_device.identification_no")
    certification_No = fields.Char(string="Certification No",related="calibration_device.certification_no")
    calibrated_date = fields.Date(string="Calibrated Date",related="calibration_device.calibrated_on")
    due_date = fields.Date(string="Due Date",related="calibration_device.calibrated_due")

class FIR_BRR_serial_no_Lines(models.Model):
    _name = 'sos_brr_serial_no_lines'
    _description = 'Serial No Line Items'

    ref_id = fields.Many2one('sos_fir_brr',  ondelete="cascade")
    serial_no = fields.Char(string="Serial No")
    inspection_decision = fields.Selection([('PASS','PASS'),('FAIL','FAIL')],string="Inspection Decision",default="PASS")