# -*- coding: utf-8 -*-
"""
Cheque Layout Settings
======================
Configurable cheque layout with visual preview.
"""

from odoo import api, fields, models, _
from odoo.exceptions import UserError
import base64


class ChequeLayoutSettings(models.Model):
    """
    Cheque Layout Settings with XY positioning for all fields.
    Includes image upload for visual preview alignment.
    """
    _name = 'cheque.layout.settings'
    _description = 'Cheque Layout Settings'
    _rec_name = 'name'

    name = fields.Char(string='Layout Name', required=True, default='Default Layout')
    active = fields.Boolean(default=True)
    is_default = fields.Boolean(string='Default Layout', default=False)
    company_id = fields.Many2one(
        'res.company',
        string='Company',
        default=lambda self: self.env.company,
        required=True,
    )
    
    # Background Image for Preview
    cheque_image = fields.Binary(
        string='Cheque Background Image',
        help='Upload your pre-printed cheque stock image for alignment preview',
    )
    cheque_image_filename = fields.Char(string='Cheque Image Filename')
    
    # =============== PAGE SETTINGS ===============
    page_width = fields.Float(string='Page Width (inches)', default=8.5)
    page_height = fields.Float(string='Page Height (inches)', default=11.0)
    
    # =============== SECTION HEIGHTS ===============
    # All values in inches from top of page
    section1_height = fields.Float(
        string='Cheque Section Height (in)',
        default=3.67,
        help='Height of the cheque section (top section)',
    )
    section2_start = fields.Float(
        string='Stub 1 Start Position (in)',
        default=3.67,
        help='Y position where stub 1 begins',
    )
    section2_height = fields.Float(
        string='Stub 1 Height (in)',
        default=3.67,
        help='Height of stub 1 (middle section)',
    )
    section3_start = fields.Float(
        string='Stub 2 Start Position (in)',
        default=7.34,
        help='Y position where stub 2 begins',
    )
    section3_height = fields.Float(
        string='Stub 2 Height (in)',
        default=3.66,
        help='Height of stub 2 (bottom section)',
    )
    
    # =============== CHEQUE SECTION POSITIONS ===============
    # Date
    date_x = fields.Float(string='Date X (in)', default=6.8)
    date_y = fields.Float(string='Date Y (in)', default=0.35)
    date_font_size = fields.Integer(string='Date Font Size (pt)', default=11)
    
    # Amount (numeric)
    amount_x = fields.Float(string='Amount X (in)', default=6.9)
    amount_y = fields.Float(string='Amount Y (in)', default=0.75)
    amount_font_size = fields.Integer(string='Amount Font Size (pt)', default=12)
    
    # Amount in Words
    amount_words_x = fields.Float(string='Amount Words X (in)', default=0.6)
    amount_words_y = fields.Float(string='Amount Words Y (in)', default=1.25)
    amount_words_font_size = fields.Integer(string='Amount Words Font Size (pt)', default=9)
    
    # Payee Name
    payee_x = fields.Float(string='Payee Name X (in)', default=0.6)
    payee_y = fields.Float(string='Payee Name Y (in)', default=1.65)
    payee_font_size = fields.Integer(string='Payee Font Size (pt)', default=11)
    
    # Payee Address (separate from name)
    payee_address_x = fields.Float(string='Payee Address X (in)', default=0.6)
    payee_address_y = fields.Float(string='Payee Address Y (in)', default=1.85)
    payee_address_font_size = fields.Integer(string='Payee Address Font Size (pt)', default=9)
    
    # Pay Period (on cheque)
    cheque_pay_period_x = fields.Float(string='Pay Period X (in)', default=0.6)
    cheque_pay_period_y = fields.Float(string='Pay Period Y (in)', default=2.1)
    
    # Memo
    memo_x = fields.Float(string='Memo X (in)', default=0.6)
    memo_y = fields.Float(string='Memo Y (in)', default=3.1)
    memo_font_size = fields.Integer(string='Memo Font Size (pt)', default=8)
    
    # =============== STUB SECTION OFFSETS ===============
    # These are relative to the section start position
    stub_padding_top = fields.Float(string='Stub Top Padding (in)', default=0.35)
    stub_padding_left = fields.Float(string='Stub Left Padding (in)', default=0.1)
    stub_padding_right = fields.Float(string='Stub Right Padding (in)', default=0.1)
    stub_padding_bottom = fields.Float(string='Stub Bottom Padding (in)', default=0.1)
    stub_full_width = fields.Boolean(string='Use Full Page Width', default=True, help='Stub content uses full page width')
    stub_center_data = fields.Boolean(string='Center Data in Stub', default=True, help='Center the stub data horizontally')
    stub_content_margin = fields.Float(string='Stub Content Margin (in)', default=0.5, help='Left and right margin for stub content when centering. Increase to push content more toward center.')
    
    # Column widths (as percentages)
    col1_width = fields.Integer(string='Column 1 Width (%)', default=22, help='Employee/Company Info')
    col2_width = fields.Integer(string='Column 2 Width (%)', default=26, help='PAY/Benefits')
    col3_width = fields.Integer(string='Column 3 Width (%)', default=26, help='Taxes/Deductions')
    col4_width = fields.Integer(string='Column 4 Width (%)', default=26, help='Summary')
    
    # Font sizes for stubs
    stub_title_font_size = fields.Integer(string='Stub Title Font Size', default=9)
    stub_content_font_size = fields.Integer(string='Stub Content Font Size', default=7)
    stub_header_font_size = fields.Integer(string='Stub Header Font Size', default=6)
    
    # =============== METHODS ===============
    
    @api.model
    def get_default_settings(self):
        """Get or create the default layout settings for the current company."""
        settings = self.search([
            ('company_id', '=', self.env.company.id),
            ('is_default', '=', True),
        ], limit=1)
        
        if not settings:
            settings = self.search([
                ('company_id', '=', self.env.company.id),
            ], limit=1)
        
        if not settings:
            settings = self.create({
                'name': 'Default Cheque Layout',
                'company_id': self.env.company.id,
                'is_default': True,
            })
        
        return settings
    
    def action_set_as_default(self):
        """Set this layout as the default for the company."""
        # Unset other defaults
        self.search([
            ('company_id', '=', self.company_id.id),
            ('is_default', '=', True),
            ('id', '!=', self.id),
        ]).write({'is_default': False})
        
        self.is_default = True
    
    def get_layout_data(self):
        """Return all layout settings as a dictionary for the report template."""
        self.ensure_one()
        return {
            'page': {
                'width': self.page_width,
                'height': self.page_height,
            },
            'sections': {
                'cheque': {
                    'height': self.section1_height,
                },
                'stub1': {
                    'start': self.section2_start,
                    'height': self.section2_height,
                },
                'stub2': {
                    'start': self.section3_start,
                    'height': self.section3_height,
                },
            },
            'cheque': {
                'date': {'x': self.date_x, 'y': self.date_y, 'font_size': self.date_font_size},
                'amount': {'x': self.amount_x, 'y': self.amount_y, 'font_size': self.amount_font_size},
                'amount_words': {'x': self.amount_words_x, 'y': self.amount_words_y, 'font_size': self.amount_words_font_size},
                'payee': {'x': self.payee_x, 'y': self.payee_y, 'font_size': self.payee_font_size},
                'pay_period': {'x': self.cheque_pay_period_x, 'y': self.cheque_pay_period_y},
                'memo': {'x': self.memo_x, 'y': self.memo_y, 'font_size': self.memo_font_size},
            },
            'stub': {
                'padding': {
                    'top': self.stub_padding_top,
                    'left': self.stub_padding_left,
                    'right': self.stub_padding_right,
                    'bottom': self.stub_padding_bottom,
                },
                'columns': {
                    'col1': self.col1_width,
                    'col2': self.col2_width,
                    'col3': self.col3_width,
                    'col4': self.col4_width,
                },
                'fonts': {
                    'title': self.stub_title_font_size,
                    'content': self.stub_content_font_size,
                    'header': self.stub_header_font_size,
                },
            },
        }
    
    def action_open_preview(self):
        """Open the visual preview configuration wizard."""
        self.ensure_one()
        # Ensure the record is saved to database (required for related fields to work)
        # Check if it's a real database ID (integer) vs a NewId
        if not isinstance(self.id, int):
            # Record not yet saved - need to save first
            raise UserError(_('Please save the record first before opening the preview.'))
        
        return {
            'type': 'ir.actions.act_window',
            'name': _('Cheque Layout Preview'),
            'res_model': 'cheque.layout.preview.wizard',
            'view_mode': 'form',
            'target': 'new',
            'context': {
                'default_settings_id': self.id,
            },
        }


class ChequeLayoutPreviewWizard(models.TransientModel):
    """
    Wizard for visual preview of cheque layout.
    Shows the cheque image with overlaid field positions.
    """
    _name = 'cheque.layout.preview.wizard'
    _description = 'Cheque Layout Preview'
    
    settings_id = fields.Many2one('cheque.layout.settings', string='Layout Settings', required=True)
    
    # Local copies of fields for editing (will be saved back to settings on close)
    cheque_image = fields.Binary(string='Cheque Background Image')
    cheque_image_filename = fields.Char(string='Cheque Image Filename')
    
    # Section positions
    section1_height = fields.Float(string='Cheque End (in)', default=3.67)
    section2_start = fields.Float(string='Stub 1 Start (in)', default=3.67)
    section3_start = fields.Float(string='Stub 2 Start (in)', default=7.34)
    
    # Cheque field positions
    date_x = fields.Float(string='Date X', default=6.8)
    date_y = fields.Float(string='Date Y', default=0.35)
    amount_x = fields.Float(string='Amount X', default=6.9)
    amount_y = fields.Float(string='Amount Y', default=0.75)
    amount_words_x = fields.Float(string='Amount Words X', default=0.6)
    amount_words_y = fields.Float(string='Amount Words Y', default=1.25)
    payee_x = fields.Float(string='Payee X', default=0.6)
    payee_y = fields.Float(string='Payee Y', default=1.65)
    payee_address_x = fields.Float(string='Payee Address X', default=0.6)
    payee_address_y = fields.Float(string='Payee Address Y', default=1.85)
    cheque_pay_period_x = fields.Float(string='Pay Period X', default=0.6)
    cheque_pay_period_y = fields.Float(string='Pay Period Y', default=2.1)
    memo_x = fields.Float(string='Memo X', default=0.6)
    memo_y = fields.Float(string='Memo Y', default=3.1)
    
    # Stub positions
    stub_padding_top = fields.Float(string='Stub Top Padding', default=0.35)
    stub_padding_left = fields.Float(string='Stub Left Padding', default=0.1)
    stub_content_margin = fields.Float(string='Stub Content Margin (in)', default=0.5)
    stub_center_data = fields.Boolean(string='Center Data in Stub', default=True)
    
    # Preview HTML (computed)
    preview_html = fields.Html(string='Preview', compute='_compute_preview_html', sanitize=False)
    
    @api.model
    def default_get(self, fields_list):
        """Load values from settings_id when wizard is opened."""
        res = super().default_get(fields_list)
        settings_id = self.env.context.get('default_settings_id')
        if settings_id:
            settings = self.env['cheque.layout.settings'].browse(settings_id)
            if settings.exists():
                res.update({
                    'cheque_image': settings.cheque_image,
                    'cheque_image_filename': settings.cheque_image_filename,
                    'section1_height': settings.section1_height,
                    'section2_start': settings.section2_start,
                    'section3_start': settings.section3_start,
                    'date_x': settings.date_x,
                    'date_y': settings.date_y,
                    'amount_x': settings.amount_x,
                    'amount_y': settings.amount_y,
                    'amount_words_x': settings.amount_words_x,
                    'amount_words_y': settings.amount_words_y,
                    'payee_x': settings.payee_x,
                    'payee_y': settings.payee_y,
                    'payee_address_x': settings.payee_address_x,
                    'payee_address_y': settings.payee_address_y,
                    'cheque_pay_period_x': settings.cheque_pay_period_x,
                    'cheque_pay_period_y': settings.cheque_pay_period_y,
                    'memo_x': settings.memo_x,
                    'memo_y': settings.memo_y,
                    'stub_padding_top': settings.stub_padding_top,
                    'stub_padding_left': settings.stub_padding_left,
                    'stub_content_margin': settings.stub_content_margin,
                    'stub_center_data': settings.stub_center_data,
                })
        return res
    
    @api.depends(
        'cheque_image', 'section1_height', 'section2_start', 'section3_start',
        'date_x', 'date_y', 'amount_x', 'amount_y', 'amount_words_x', 'amount_words_y',
        'payee_x', 'payee_y', 'payee_address_x', 'payee_address_y',
        'cheque_pay_period_x', 'cheque_pay_period_y',
        'memo_x', 'memo_y', 'stub_padding_top', 'stub_padding_left'
    )
    def _compute_preview_html(self):
        """Generate HTML preview with overlaid positions."""
        for wizard in self:
            # Scale factor: 1 inch = 72 pixels for preview
            scale = 72
            page_width = 8.5 * scale
            page_height = 11 * scale
            
            # Build background image style
            bg_style = ''
            if wizard.cheque_image:
                image_data = wizard.cheque_image.decode('utf-8') if isinstance(wizard.cheque_image, bytes) else wizard.cheque_image
                bg_style = f'background-image: url(data:image/png;base64,{image_data}); background-size: 100% 100%;'
            
            # Helper to convert inches to pixels
            def px(inches):
                return (inches or 0) * scale
            
            # Section divider lines
            section_lines = f'''
                <div style="position: absolute; top: {px(wizard.section1_height)}px; left: 0; right: 0; 
                     border-bottom: 2px dashed red; z-index: 10;">
                    <span style="background: red; color: white; font-size: 10px; padding: 2px 4px;">
                        Cheque End ({wizard.section1_height:.2f} in)
                    </span>
                </div>
                <div style="position: absolute; top: {px(wizard.section3_start)}px; left: 0; right: 0; 
                     border-bottom: 2px dashed red; z-index: 10;">
                    <span style="background: red; color: white; font-size: 10px; padding: 2px 4px;">
                        Stub 2 Start ({wizard.section3_start:.2f} in)
                    </span>
                </div>
            '''
            
            # Field markers (cheque section)
            field_markers = f'''
                <!-- Date -->
                <div style="position: absolute; left: {px(wizard.date_x)}px; top: {px(wizard.date_y)}px;
                     background: rgba(0,128,255,0.9); color: white; padding: 2px 6px; font-size: 10px; 
                     border: 1px solid blue; z-index: 20; white-space: nowrap;">
                    DATE: JAN 11, 2026
                </div>
                
                <!-- Amount -->
                <div style="position: absolute; left: {px(wizard.amount_x)}px; top: {px(wizard.amount_y)}px;
                     background: rgba(0,180,0,0.9); color: white; padding: 2px 6px; font-size: 10px; 
                     border: 1px solid green; z-index: 20; white-space: nowrap;">
                    **1,465.19
                </div>
                
                <!-- Amount in Words -->
                <div style="position: absolute; left: {px(wizard.amount_words_x)}px; top: {px(wizard.amount_words_y)}px;
                     background: rgba(255,128,0,0.9); color: white; padding: 2px 6px; font-size: 9px; 
                     border: 1px solid orange; z-index: 20; white-space: nowrap;">
                    AMOUNT IN WORDS
                </div>
                
                <!-- Payee Name -->
                <div style="position: absolute; left: {px(wizard.payee_x)}px; top: {px(wizard.payee_y)}px;
                     background: rgba(128,0,255,0.9); color: white; padding: 2px 6px; font-size: 10px; 
                     border: 1px solid purple; z-index: 20; white-space: nowrap;">
                    PAYEE NAME
                </div>
                
                <!-- Payee Address -->
                <div style="position: absolute; left: {px(wizard.payee_address_x)}px; top: {px(wizard.payee_address_y)}px;
                     background: rgba(180,0,180,0.9); color: white; padding: 2px 6px; font-size: 9px; 
                     border: 1px solid #b400b4; z-index: 20; white-space: nowrap;">
                    PAYEE ADDRESS
                </div>
                
                <!-- Pay Period -->
                <div style="position: absolute; left: {px(wizard.cheque_pay_period_x)}px; top: {px(wizard.cheque_pay_period_y)}px;
                     background: rgba(255,0,128,0.9); color: white; padding: 2px 6px; font-size: 9px; 
                     border: 1px solid #ff0080; z-index: 20; white-space: nowrap;">
                    PAY PERIOD
                </div>
                
                <!-- Memo -->
                <div style="position: absolute; left: {px(wizard.memo_x)}px; top: {px(wizard.memo_y)}px;
                     background: rgba(128,128,128,0.9); color: white; padding: 2px 6px; font-size: 9px; 
                     border: 1px solid gray; z-index: 20; white-space: nowrap;">
                    MEMO
                </div>
            '''
            
            # Stub markers - full width centered
            stub1_top = (wizard.section2_start or 0) + (wizard.stub_padding_top or 0)
            stub2_top = (wizard.section3_start or 0) + (wizard.stub_padding_top or 0)
            
            stub_markers = f'''
                <!-- Stub 1 Content Area (Full Width, Centered) -->
                <div style="position: absolute; left: {px(wizard.stub_padding_left)}px; top: {px(stub1_top)}px;
                     right: {px(wizard.stub_padding_left)}px; height: 200px;
                     border: 2px dashed #00aa00; z-index: 15; display: flex; align-items: flex-start; justify-content: center;">
                    <span style="background: #00aa00; color: white; font-size: 10px; padding: 2px 6px;">
                        STUB 1 - FULL WIDTH CENTERED
                    </span>
                </div>
                
                <!-- Stub 2 Content Area (Full Width, Centered) -->
                <div style="position: absolute; left: {px(wizard.stub_padding_left)}px; top: {px(stub2_top)}px;
                     right: {px(wizard.stub_padding_left)}px; height: 200px;
                     border: 2px dashed #0000aa; z-index: 15; display: flex; align-items: flex-start; justify-content: center;">
                    <span style="background: #0000aa; color: white; font-size: 10px; padding: 2px 6px;">
                        STUB 2 - FULL WIDTH CENTERED
                    </span>
                </div>
            '''
            
            wizard.preview_html = f'''
                <div style="position: relative; width: {page_width}px; height: {page_height}px; 
                     border: 1px solid #ccc; {bg_style} overflow: hidden; margin: 0 auto; background-color: #f8f8f8;">
                    {section_lines}
                    {field_markers}
                    {stub_markers}
                </div>
            '''
    
    def action_save_and_close(self):
        """Save changes back to settings and close the wizard."""
        self.ensure_one()
        if self.settings_id:
            self.settings_id.write({
                'cheque_image': self.cheque_image,
                'cheque_image_filename': self.cheque_image_filename,
                'section1_height': self.section1_height,
                'section2_start': self.section2_start,
                'section3_start': self.section3_start,
                'date_x': self.date_x,
                'date_y': self.date_y,
                'amount_x': self.amount_x,
                'amount_y': self.amount_y,
                'amount_words_x': self.amount_words_x,
                'amount_words_y': self.amount_words_y,
                'payee_x': self.payee_x,
                'payee_y': self.payee_y,
                'payee_address_x': self.payee_address_x,
                'payee_address_y': self.payee_address_y,
                'cheque_pay_period_x': self.cheque_pay_period_x,
                'cheque_pay_period_y': self.cheque_pay_period_y,
                'memo_x': self.memo_x,
                'memo_y': self.memo_y,
                'stub_padding_top': self.stub_padding_top,
                'stub_padding_left': self.stub_padding_left,
                'stub_content_margin': self.stub_content_margin,
                'stub_center_data': self.stub_center_data,
            })
        return {'type': 'ir.actions.act_window_close'}
    
    def action_print_test(self):
        """Save current wizard values and print a test cheque."""
        self.ensure_one()
        
        # First, save current wizard values to the settings record
        if self.settings_id:
            self.settings_id.write({
                'cheque_image': self.cheque_image,
                'cheque_image_filename': self.cheque_image_filename,
                'section1_height': self.section1_height,
                'section2_start': self.section2_start,
                'section3_start': self.section3_start,
                'date_x': self.date_x,
                'date_y': self.date_y,
                'amount_x': self.amount_x,
                'amount_y': self.amount_y,
                'amount_words_x': self.amount_words_x,
                'amount_words_y': self.amount_words_y,
                'payee_x': self.payee_x,
                'payee_y': self.payee_y,
                'payee_address_x': self.payee_address_x,
                'payee_address_y': self.payee_address_y,
                'cheque_pay_period_x': self.cheque_pay_period_x,
                'cheque_pay_period_y': self.cheque_pay_period_y,
                'memo_x': self.memo_x,
                'memo_y': self.memo_y,
                'stub_padding_top': self.stub_padding_top,
                'stub_padding_left': self.stub_padding_left,
                'stub_content_margin': self.stub_content_margin,
                'stub_center_data': self.stub_center_data,
            })
        
        # Find a sample cheque to print
        cheque = self.env['payroll.cheque'].search([], limit=1)
        if cheque:
            return self.env.ref('fusion_payroll.action_report_payroll_cheque').report_action(cheque)
        else:
            raise UserError(_('No cheque records found to print test.'))
