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

from odoo import models, fields, api
from odoo.exceptions import ValidationError
from datetime import datetime
import base64
from io import BytesIO
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, Border, Side
from openpyxl.utils import get_column_letter

class StockMovementReportWizard(models.TransientModel):
    _name = 'stock_movement_report_wizard'
    _description = 'Stock Movement Report Wizard'

    date_from = fields.Date(string='From Date', required=True, default=lambda self: datetime.now().replace(day=1))
    date_to = fields.Date(string='To Date', required=True, default=lambda self: datetime.now())
    excel_file = fields.Binary(string='Excel Report', readonly=True)
    file_name = fields.Char(string='File Name', readonly=True)

    def generate_excel_report(self):
        """Generate and download the Excel report."""
        if self.date_from > self.date_to:
            raise ValidationError("From Date must be before To Date.")

        # Prepare data and generate Excel file
        data = self._prepare_report_data()
        excel_file = self._generate_excel(data)

        # Save the file and ensure the record is persisted
        self.write({
            'excel_file': excel_file,
            'file_name': f"Stock_Movement_Report_{self.date_from}_to_{self.date_to}.xlsx"
        })

        # Commit the transaction to ensure the record is saved
        self.env.cr.commit()

        # Verify the file was saved
        if not self.excel_file:
            raise ValidationError("Failed to generate or save the Excel file.")

        # Return URL-based download action
        return {
            'type': 'ir.actions.act_url',
            'url': f'/web/content?model={self._name}&id={self.id}&field=excel_file&filename_field=file_name&download=true',
            'target': 'self',
        }

    def _prepare_report_data(self):
        """Prepare data for full stock movement summary report."""
        domain = [('date', '>=', self.date_from), ('date', '<=', self.date_to)]
        transactions = self.env['sos_material_transaction_history'].search(domain)

        # Build material data with in/out qty and price
        material_summary = {}
        for trans in transactions:
            mat = trans.ref_id
            if mat.id not in material_summary:
                material_summary[mat.id] = {
                    'part_no': mat.part_no,
                    'name': mat.name or '',
                    'uom': mat.uom,
                    'price': round(mat.unit_price or 0.0, 2),
                    'opening_bal_qty':mat.opening_bal_qty,
                    'in_qty': 0.0,
                    'out_qty': 0.0,
                }
            if trans.action == 'in':
                material_summary[mat.id]['in_qty'] += trans.quantity
            elif trans.action == 'out':
                material_summary[mat.id]['out_qty'] += trans.quantity

        # Include materials with no transactions as well
        all_materials = self.env['sos_material'].search([])
        for mat in all_materials:
            if mat.id not in material_summary:
                material_summary[mat.id] = {
                    'part_no': mat.part_no,
                    'name': mat.name or '',
                    'uom': mat.uom,
                    'price': round(mat.unit_price or 0.0, 2),
                    'opening_bal_qty':mat.opening_bal_qty,
                    'in_qty': 0.0,
                    'out_qty': 0.0,
                }

        return {
            'date_from': self.date_from,
            'date_to': self.date_to,
            'summary': list(material_summary.values())
        }


    def _generate_excel(self, data):
        """Generate Excel file showing all material movements within date range."""
        

        wb = Workbook()
        ws = wb.active
        ws.title = "All Material Movement"

        # Styles
        header_font = Font(bold=True)
        header_align = Alignment(horizontal='center', vertical='center')
        border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin'),
        )

        # Title
        ws['A1'] = f"Material Movement Report ({data['date_from']} to {data['date_to']})"
        ws.merge_cells('A1:F1')
        ws['A1'].font = Font(bold=True, size=14)
        ws['A1'].alignment = header_align

        # Header Row
        row = 3
        headers = ["Part No", "Name", "UOM", "Price","Opening Balance(Sep 2-2024)", "In Qty", "Out Qty"]
        for col, header in enumerate(headers, 1):
            cell = ws.cell(row=row, column=col)
            cell.value = header
            cell.font = header_font
            cell.alignment = header_align
            cell.border = border
        row += 1

        # Data Rows
        for stock in data['summary']:
            ws.cell(row=row, column=1).value = stock['part_no']
            ws.cell(row=row, column=2).value = stock['name']
            ws.cell(row=row, column=3).value = stock['uom']
            ws.cell(row=row, column=4).value = round(stock['price'], 2)
            ws.cell(row=row, column=5).value = stock['opening_bal_qty']
            ws.cell(row=row, column=6).value = stock['in_qty']
            ws.cell(row=row, column=7).value = stock['out_qty']
            for col in range(1, 8):
                ws.cell(row=row, column=col).border = border
            row += 1

        # Adjust column widths
        for col in range(1, 8):
            max_length = 0
            col_letter = get_column_letter(col)
            for r in ws.iter_rows(min_row=1, max_row=ws.max_row, min_col=col, max_col=col):
                for cell in r:
                    if cell.value:
                        max_length = max(max_length, len(str(cell.value)))
            ws.column_dimensions[col_letter].width = max_length + 2

        # Save to BytesIO and return as base64
        output = BytesIO()
        wb.save(output)
        output.seek(0)
        return base64.b64encode(output.read())
