# -*- coding: utf-8 -*-

from odoo import models, fields, api
import re

class sos__dc(models.Model):
    _name = 'sos_dc'
    _description = 'Delivery Challan'
    _rec_name = 'dc_no'
    _order = 'id desc'

    def _default_invoicing_address(self):
        html_content = self.env.company.company_details
        if not isinstance(html_content, str):
            html_content = str(html_content)
        clean_text = re.sub(r'</p>', '\n', html_content)
        clean_text = re.sub(r'<[^>]+>', '', clean_text)
        lines = clean_text.split('\n')
        for line in lines:
            if line.strip():  
                line.strip()
        return clean_text



    dc_no = fields.Char(string="D.C No", readonly= True, required= True, default=lambda self: self._generate_id())
    dock_audit_no = fields.Many2one('sos_dock_audit',string="Fill Challan against Dock Audit")
    dc_date = fields.Datetime(string="D.C Date",required=True)
    dispatch_mode=fields.Selection([('By Courier', 'By Courier'),('By Hand', 'By Hand'),('By Direct Delivery', 'By Direct Delivery')],string="Mode of Dispatch")
    from_station = fields.Char(string="From Station",default="Sosaley Technologies Private Limited,Chennai")
    to_station = fields.Char(string="To Station")
    sosaley_gst_no = fields.Char(string="Sosaley GST No",default="33AACCJ0045R1ZI")
    customer_gst_no = fields.Char(string="Customer GST No")
    purpose = fields.Char(string="Remarks")
    purpose_remarks=fields.Selection([('Outsourcing', 'Outsourcing'),('Sales', 'Sales'),('I&C / Service', 'I&C / Service'),('Demo', 'Demo'),('Validation', 'Validation'),('Warranty', 'Warranty')],string="Purpose")
    indent_no  = fields.Many2one('sos_fg_plan', string='Ref No')
    po_no = fields.Char(string="PO No")
    invoice_no = fields.Char(string="Invoice No")
    carried_by = fields.Many2one('res.users', string='Carried By')
    billing_address = fields.Text(string="Billing Address")
    to_address = fields.Text(string="Shipping Address")
    approval_name = fields.Many2one('res.users', string='Prepared By')
    approval_image = fields.Image(related="approval_name.signature_image",string='Authorised Signatory',readonly=True)
    approved_on = fields.Datetime(string="Approved On")
    line_ids = fields.One2many('sos_dc_line', 'dc_id')
    line_ids_miscellaneous = fields.One2many('sos_dc_line_miscellaneous', 'dc_id')
    line_ids_materials = fields.One2many('sos_dc_line_material', 'dc_id')
    line_ids_sfg = fields.One2many('sos_dc_line_sfg', 'dc_id')
    line_ids_fg = fields.One2many('sos_dc_line_fg', 'dc_id')
    dc_type = fields.Selection([ ('others', 'Others'),('out_souce_return', 'Outsourcing / Returnable'),('out_souce_noreturn', 'Outsourcing / Non-Returnable'),('customer_return', 'Customer / Returnable'),('customer_noreturn', 'Customer / Non-Returnable')], default='customer_return' , string="Type")
    wo_no = fields.Many2one('sos_wo', string="W.O No", domain="[('wo_status', '=', 'open')]")
    auto_load_sfg_items = fields.Many2many('sos_sfg', string='SFG Name')
    auto_load_sfg_items_domain = fields.Char(compute='_compute_auto_load_sfg_items_domain')
    order_qty = fields.Integer(string="Order Quantity",default=1)
    service_provider_name = fields.Many2one('sos_service_providers',string="Service Provider Name")
    top_management_name = fields.Many2one('res.users', string='Top Management Approver')
    top_management_approval_image = fields.Image(related="top_management_name.signature_image",string='Top Management Approval',readonly=True)
    top_management_approved_on = fields.Datetime(string="Approved On")
    dept_in_charge_name = fields.Many2one('res.users', string='Department In-Charge')
    dept_in_charge_image = fields.Image(related="dept_in_charge_name.signature_image",string='Department In-Charge Sign',readonly=True)
    dept_in_charge_approved_on = fields.Datetime(string="Approved On")
    remarks = fields.Text(string="Remarks")

    @api.onchange('dock_audit_no')
    def _onchange_dock_audit_no(self):
        if self.dock_audit_no:
            self.billing_address = self.dock_audit_no.billing_address
            self.to_address = self.dock_audit_no.shipping_address
            self.po_no = self.dock_audit_no.customer_po_no
            self.purpose = self.dock_audit_no.purpose
            self.invoice_no = self.dock_audit_no.invoice_no
            self.customer_gst_no = self.dock_audit_no.gst_no
            self.line_ids_materials = [(5, 0, 0)] 
            self.line_ids_materials = [
                (0, 0, {
                    'component_id': line.component_id,  
                    'uom': line.uom,
                    'qty': line.quantity
                }) for line in self.dock_audit_no.line_ids_material
            ]
            self.line_ids_materials = [
                (0, 0, {
                    'component_id': line.component_id,  
                    'uom': line.uom,
                    'qty': line.quantity
                }) for line in self.dock_audit_no.line_ids_installation_kit
            ]
            self.line_ids_sfg = [(5, 0, 0)] 
            self.line_ids_sfg = [
                (0, 0, {
                    'component_id': line.component_id,  
                    'uom': line.uom,
                    'qty': line.quantity
                }) for line in self.dock_audit_no.line_ids_sfg
            ]
            self.line_ids_fg = [(5, 0, 0)] 
            self.line_ids_fg = [
                (0, 0, {
                    'component_id': line.component_id,  
                    'uom': line.uom,
                    'qty': line.quantity
                }) for line in self.dock_audit_no.line_ids_fg
            ]
            self.line_ids_miscellaneous = [(5, 0, 0)] 
            self.line_ids_miscellaneous = [
                (0, 0, {
                    'description': line.name,  
                    'qty': line.quantity
                }) for line in self.dock_audit_no.line_ids_miscellaneous
            ]

    @api.onchange('service_provider_name')
    def _onchange_service_provider_name(self):
        if self.service_provider_name and (self.dc_type == 'out_souce_return' or self.dc_type == 'out_souce_noreturn'):
            if self.service_provider_name.address:
                self.to_address = self.service_provider_name.address
                self.to_station = self.service_provider_name.service_provider_name
            else:
                self.to_address = False  
                self.to_station = False
        else:
            self.to_address = False
            self.to_station = False
    @api.onchange('order_qty')
    def _onchange_order_qty(self):
        if self.auto_load_sfg_items:
            self.line_ids = [(5, 0, 0)] 

            for sfg_item in self.auto_load_sfg_items:
                sfg_record = self.env['sos_sfg_bom'].search([('name', '=', sfg_item.name)], limit=1)
                
                if sfg_record:
                    sfg_materials = self.env['sos_sfg_bom_line'].search([('bom_id', '=', sfg_record.id)])
                    
                    material_lines = []
                    for material in sfg_materials:
                        line_vals = {
                            'component_id': material.primary_component_id.id,
                            'uom': material.primary_component_id.uom,  
                            'req_qty': material.quantity * self.order_qty,
                            'given_qty': material.quantity * self.order_qty,
                            'uom': 'Nos' 
                        }
                        material_lines.append((0, 0, line_vals))
                    
                    self.line_ids = material_lines
                else:
                    print(f"No matching BOM found for the selected SFG item: {sfg_item.name}")

    @api.depends('wo_no')
    def _compute_auto_load_sfg_items_domain(self):
        for record in self:
            if record.wo_no:
                component_ids = record.wo_no.line_ids.mapped('component_id.id')
                record.auto_load_sfg_items_domain = [('id', 'in', component_ids)]
            else:
                record.auto_load_sfg_items_domain = []

    @api.onchange('auto_load_sfg_items')
    def _onchange_auto_load_sfg_items(self):
        if self.auto_load_sfg_items:
            # Clear existing lines first
            self.line_ids = [(5, 0, 0)]  # This clears the existing lines
            
            # Loop through each selected item in the Many2many field
            for sfg_item in self.auto_load_sfg_items:
                # Search for the SFG record
                sfg_record = self.env['sos_sfg_bom'].search([('name', '=', sfg_item.name)], limit=1)
                
                if sfg_record:
                    # Get all materials related to the selected SFG
                    sfg_materials = self.env['sos_sfg_bom_line'].search([('bom_id', '=', sfg_record.id)])
                    
                    # Loop through the materials and prepare the data
                    material_lines = []
                    for material in sfg_materials:
                        line_vals = {
                            'component_id': material.primary_component_id.id,
                            'uom': material.primary_component_id.uom,  # Ensure the UOM field is correctly referenced
                            'req_qty': material.quantity,
                            'given_qty': material.quantity,
                            'uom': 'Nos'  # Update UOM if needed
                        }
                        # Append the material lines as a tuple (0, 0, line_vals)
                        material_lines.append((0, 0, line_vals))
                    
                    # Assign the new lines to the line_ids field
                    self.line_ids = material_lines
                else:
                    print(f"No matching BOM found for the selected SFG item: {sfg_item.name}")

    def _generate_id(self):
        sequence_util = self.env['sos_common_scripts']
        return sequence_util.generate_sequence('sos_dc','DC', 'dc_no')

    def action_report_dc_btn(self):
        try:
            action = self.env.ref("sos_inventory.action_report_dc").report_action(self)
            return action
        except ValueError as e:
            print(f"Failed to find report action: {e}")

    def approved_by_sign_btn(self):
        # Email part
        body_html = f"""
        <p>Below <b>DC</b> is waiting for your Approval</p>
        """
        subject = f"Delivery Challan Approval Request - {self.dc_no}"
        sequence_util = self.env['sos_common_scripts']
        sequence_util.send_mon_min_email(self.env,"sos_dc",self.id,"deenalaura.m@sosaley.in",subject,body_html,"user")
        sequence_util.action_assign_signature(
        self, 
        'approval_name',
        'approved_on'
        )
    def deptincharge_sign_btn(self):
        # Email part
        body_html = f"""
        <p>Below <b>DC</b> is waiting for your Approval</p>
        """
        subject = f"Delivery Challan Approval Request - {self.dc_no}"
        send_email = self.env['sos_common_scripts']
        send_email.send_direct_email(self.env,"sos_dc",self.id,"ramachandran.r@sosaley.in",subject,body_html)
        # Email part ends
        sequence_util = self.env['sos_common_scripts']
        sequence_util.action_assign_signature(
        self, 
        'dept_in_charge_name',
        'dept_in_charge_approved_on'
        )
    
    def action_top_esign(self):
        if self.wo_no:
            sos_dc_record = self.env['sos_wo'].search([('id', '=', self.wo_no.id)], limit=1)
            if sos_dc_record:
                sos_dc_record.write({'dc_no': self.id}) 
        sequence_util = self.env['sos_common_scripts']
        sequence_util.action_assign_signature(
        self, 
        'top_management_name',
        'top_management_approved_on',
        'sos_inventory.sos_management_user'
        )
        # Email part
        body_html = f"""
        <p>Below <b>DC</b> was Approved</p>
        """
        
        send_email = self.env['sos_common_scripts']
        send_email.send_direct_email(self.env,"sos_dc",self.id,self.approval_name.login,"Delivery Challan Approved",body_html)
        # Email part ends
class DC_Line(models.Model):
    _name = 'sos_dc_line'
    _description = 'DC Lines'

    dc_id = fields.Many2one('sos_dc', ondelete="cascade")
    description = fields.Char(string="Description")
    qty = fields.Integer(string="Quantity")
    uom = fields.Selection([('Nos', 'Nos'),('litre', 'litre'), ('meters', 'Meters'), ('Strips', 'Strips'), ('Packs', 'Packs')], string="Uom", default='Nos')
    component_id = fields.Many2one('sos_material', string="Material Part No")
    req_qty = fields.Integer(string="Required Quantity")
    given_qty = fields.Integer(string="Given Quantity")
    display_name = fields.Char(string="Material Name", compute="_compute_display_name", store=True)

    @api.depends('component_id')
    def _compute_display_name(self):
        for record in self:
            if record.component_id:
                record.display_name = record.component_id.name or record.component_id.part_no
            else:
                record.display_name = False  # or an empty string ''

class DC_Line_miscellaneous(models.Model):
    _name = 'sos_dc_line_miscellaneous'
    _description = 'DC Lines Miscellaneous'

    dc_id = fields.Many2one('sos_dc', ondelete="cascade")
    description = fields.Char(string="Description")
    qty = fields.Integer(string="Quantity")
    uom = fields.Selection([('Nos', 'Nos'),('litre', 'litre'), ('meters', 'Meters'), ('Strips', 'Strips')], string="Uom", default='Nos')

class DC_Line_Materials(models.Model):
    _name = 'sos_dc_line_material'
    _description = 'DC Lines Material'

    dc_id = fields.Many2one('sos_dc', ondelete="cascade")
    qty = fields.Integer(string="Quantity")
    uom = fields.Selection([('Nos', 'Nos'),('litre', 'litre'), ('meters', 'Meters'), ('Strips', 'Strips')], string="Uom", default='Nos')
    component_id = fields.Many2one('sos_material', string="Material Part No")
    display_name = fields.Char(string="Material Name", compute="_compute_display_name", store=True)


    @api.depends('component_id')
    def _compute_display_name(self):
        for record in self:
            if record.component_id:
                record.display_name = record.component_id.name or record.component_id.part_no
            else:
                record.display_name = False  # or an empty string ''

class DC_Line_SFG(models.Model):
    _name = 'sos_dc_line_sfg'
    _description = 'DC Lines SFG'

    dc_id = fields.Many2one('sos_dc', ondelete="cascade")
    qty = fields.Integer(string="Quantity")
    uom = fields.Selection([('Nos', 'Nos'),('set', 'Set')], string="Uom", default='Nos')
    component_id = fields.Many2one('sos_sfg', string="SFG Name")

class DC_Line_FG(models.Model):
    _name = 'sos_dc_line_fg'
    _description = 'DC Lines FG'

    dc_id = fields.Many2one('sos_dc', ondelete="cascade")
    qty = fields.Integer(string="Quantity")
    uom = fields.Selection([('Nos', 'Nos'),('set', 'Set')], string="Uom", default='Nos')
    component_id = fields.Many2one('sos_fg', string="FG Name")
    serial_no = fields.Char(string="Serial No")
