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

from odoo import models, fields, api
from odoo.exceptions import ValidationError
from math import isnan
import io
import xlsxwriter
from odoo.tools.misc import xlsxwriter
import base64

class SOS_Sfg_Bom(models.Model):
    _name = 'sos_sfg_bom'
    _description = 'BOM of Semi-Finished Goods'

    name = fields.Many2one('sos_sfg', string="BOM Name")
    fg_name = fields.Many2many('sos_fg', string="Belongs To")
    prepared_by_name = fields.Many2one('res.users', string='Prepared by')    
    reporting_to = fields.Many2one('res.users',related="prepared_by_name.reporting_to", string='Prepared by')
    bom_version=fields.Char(string="BOM Version")
    pcb_version=fields.Char(string="PCB Version")
    assembling_charges = fields.Monetary(related="name.assembling_charges",string="Assembling Charges")
    sfg_bom_line_ids = fields.One2many('sos_sfg_bom_line', 'bom_id', string='BOM Lines', copy=True, ondelete='cascade')
    currency_id = fields.Many2one('res.currency', string='Currency')
    overall_total = fields.Monetary(store=True,compute='_compute_overall_total', string="Overall Total", currency_field='currency_id')
    material_bom_line_ids = fields.Many2many(
        'sos_material_bom',                        # Target model
        'sos_sfg_bom_sos_material_bom_rel',        # Relation table
        'sos_sfg_bom_id',                             # Column for "sos_sfg_bom"
        'sos_material_bom_id',                     # Column for "sos_material_bom"
        string='Material BOM Lines',
        copy=True
    )
    def action_export(self):
        output = io.BytesIO()
        workbook = xlsxwriter.Workbook(output, {'in_memory': True})

        headers = {
            'material_code' : 'Material Code',
            'primary_component_id': 'Material Name',
            'quantity': 'Quantity',
            'inhand_stock_qty':'Inhand Qty',
            'uom':'UOM',
            'unit_price':'Unit Price',
            'total_cost':'Total'
        }  
        
        self._write_sheet(workbook, 'Materials', self.sfg_bom_line_ids, headers)
        workbook.close()
        output.seek(0)

        attachment = self.env['ir.attachment'].create({
            'name': f'{self.name.name}_Export.xlsx',
            'type': 'binary',
            'datas': base64.b64encode(output.read()),
            'res_model': self._name,
            'res_id': self.id,
            'mimetype': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        })

        return {
            'type': 'ir.actions.act_url',
            'url': f'/web/content/{attachment.id}?download=true',
            'target': 'self',
        }

    def _write_sheet(self, workbook, sheet_name, line_records, headers):
        worksheet = workbook.add_worksheet(sheet_name)
    
        number_format = workbook.add_format({'num_format': '#,##0.00'})
        bold_format = workbook.add_format({'bold': True})
        name_value = getattr(self, 'name', False)
        worksheet.write(0, 0, 'Name',bold_format)  # Label for the first value
        worksheet.write(0, 1, name_value.display_name if name_value else '')  # Handle Many2one field

        assembling_charges = getattr(self, 'assembling_charges', 0.0)
        worksheet.write(1, 0, 'Assembly Charges',bold_format)  # Label for the second value
        worksheet.write(1, 1, assembling_charges, number_format)  # Assume numeric (float)

        overall_total = getattr(self, 'overall_total', 0.0)
        worksheet.write(2, 0, 'Overall Cost (Including assembling charges)',bold_format)  # Label for the third value
        worksheet.write(2, 1, overall_total, number_format)  # Assume numeric (float)

        for col, header in enumerate(headers.values()):
            worksheet.write(4, col, header,bold_format)

        for row, record in enumerate(line_records, start=5):
            for col, field in enumerate(headers.keys()):
                value = getattr(record, field, '')
                if isinstance(value, models.Model):
                    worksheet.write(row, col, value.display_name if value else '')
                elif isinstance(value, (fields.Date, fields.Datetime)):
                    worksheet.write(row, col, value.strftime('%Y-%m-%d') if value else '')
                else:
                    worksheet.write(row, col, value)
    @api.depends('sfg_bom_line_ids.total_cost', 'assembling_charges')
    def _compute_overall_total(self):
        for record in self:
            total_costs = sum(
                0 if line.total_cost is None or isnan(line.total_cost) else line.total_cost
                for line in record.sfg_bom_line_ids
            )
            assembling_charges = 0 if isnan(record.assembling_charges) else record.assembling_charges
            record.overall_total = total_costs + assembling_charges
    def write(self, vals):
        res = super(SOS_Sfg_Bom, self).write(vals)
        self._sync_unit_price_with_sfg()
        return res
    @api.model
    def create(self, vals):
        res = super(SOS_Sfg_Bom, self).create(vals)
        res._sync_unit_price_with_sfg()
        return res
    def _sync_unit_price_with_sfg(self):
        sos_sfg_obj = self.env['sos_sfg']
        for record in self:
            sfg_record = sos_sfg_obj.search([('name', '=', record.name.name)], limit=1)

            if sfg_record:
                sfg_record.write({'unit_price': record.overall_total})

    def action_bulk_upload(self):
        view_id = self.env.ref('sos_inventory.bulk_upload_wizard_form').id
        return {
            'type': 'ir.actions.act_window',
            'name': 'Bulk Upload',
            'res_model': 'bulk_upload_wizard',
            'view_mode': 'form',
            'views': [(view_id, 'form')],
            'target': 'new',
            'context': {
            'default_sos_sfg_id': self.id
        }
        }



class SOS_Sfg_Bom_Line(models.Model):
    _name = 'sos_sfg_bom_line'
    _description = 'BOM Lines of Semi-Finished Goods'

    bom_id = fields.Many2one('sos_sfg_bom', string="SFG BOM Reference")
    fg_bom_id = fields.Many2one('sos_fg_bom', string="FG BOM Reference")
    primary_component_id = fields.Many2one('sos_material', string='Part No', required=True)
    location = fields.Char(related="primary_component_id.location")
    inhand_stock_qty = fields.Float(related="primary_component_id.inhand_stock_qty")
    material_code = fields.Char(related="primary_component_id.material_code")
    quantity = fields.Float(string="Qty", default=1)
    inspection_method = fields.Integer(related="primary_component_id.inspection_method",string='Inspection Method',readonly=False)
    currency_id = fields.Many2one('res.currency', string='Currency')
    unit_price = fields.Monetary(related='primary_component_id.unit_price', string="Unit Price", currency_field='currency_id', readonly=True)
    uom = fields.Selection(
    related='primary_component_id.uom', 
    string="UOM"
    )
    total_cost = fields.Monetary(compute='_compute_total_cost', string="Total Cost", currency_field='currency_id', readonly=True)
    @api.depends('unit_price', 'quantity')
    def _compute_total_cost(self):
        for record in self:
            record.total_cost = record.unit_price * record.quantity

    @api.onchange('inspection_method')
    def _onchange_inspection_method(self):
        if self.inspection_method:
            self.primary_component_id.inspection_method = self.inspection_method
    # @api.model
    # def create(self, vals):
    #     existing_record = self.search([
    #         ('primary_component_id', '=', vals.get('primary_component_id')),
    #         ('fg_bom_id', '=', vals.get('fg_bom_id'))
    #     ], limit=1)
    #     if existing_record:
    #         existing_record.quantity += vals.get('quantity', 0)
    #         return existing_record
    #     else:
    #         return super(SOS_Sfg_Bom_Line, self).create(vals)


