# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)

import base64
import json
import logging
from datetime import datetime, timedelta
from odoo import http, fields, _
from odoo.http import request
from odoo.addons.portal.controllers.portal import CustomerPortal

_logger = logging.getLogger(__name__)


class FusionClockPortal(CustomerPortal):
    """Portal controller for Fusion Clock pages."""

    def _prepare_portal_layout_values(self):
        """Inject clock FAB data into every portal page context."""
        values = super()._prepare_portal_layout_values()
        employee = self._get_portal_employee()
        if employee and employee.x_fclk_enable_clock:
            is_checked_in = employee.attendance_state == 'checked_in'
            check_in_time = ''
            location_name = ''
            if is_checked_in:
                att = request.env['hr.attendance'].sudo().search([
                    ('employee_id', '=', employee.id),
                    ('check_out', '=', False),
                ], limit=1)
                if att:
                    check_in_time = att.check_in.isoformat() if att.check_in else ''
                    location_name = att.x_fclk_location_id.name if att.x_fclk_location_id else ''
            values.update({
                'fclk_employee': employee,
                'fclk_checked_in': is_checked_in,
                'fclk_check_in_time': check_in_time,
                'fclk_location_name': location_name,
            })
        else:
            values['fclk_employee'] = False
        return values

    def _prepare_home_portal_values(self, counters):
        """Add clock counters to the portal home page."""
        values = super()._prepare_home_portal_values(counters)
        if 'clock_count' in counters:
            employee = self._get_portal_employee()
            if employee:
                today_start = datetime.combine(fields.Date.today(), datetime.min.time())
                count = request.env['hr.attendance'].sudo().search_count([
                    ('employee_id', '=', employee.id),
                    ('check_in', '>=', today_start),
                ])
                values['clock_count'] = count
        return values

    def _get_portal_employee(self):
        """Get the employee record for the current portal/internal user."""
        user = request.env.user
        employee = request.env['hr.employee'].sudo().search([
            ('user_id', '=', user.id),
        ], limit=1)
        return employee

    # =========================================================================
    # Clock Page
    # =========================================================================

    @http.route('/my/clock', type='http', auth='user', website=True)
    def portal_clock(self, **kw):
        """Main clock-in/out portal page."""
        employee = self._get_portal_employee()
        if not employee:
            return request.redirect('/my')

        ICP = request.env['ir.config_parameter'].sudo()
        google_maps_key = ICP.get_param('fusion_clock.google_maps_api_key', '')
        enable_sounds = ICP.get_param('fusion_clock.enable_sounds', 'True') == 'True'

        # Get locations
        Location = request.env['fusion.clock.location'].sudo()
        locations = Location.search([
            ('active', '=', True),
            ('company_id', '=', employee.company_id.id),
        ])
        locations = locations.filtered(
            lambda loc: loc.all_employees or employee.id in loc.employee_ids.ids
        )

        # Current attendance status
        is_checked_in = employee.attendance_state == 'checked_in'
        current_attendance = False
        if is_checked_in:
            current_attendance = request.env['hr.attendance'].sudo().search([
                ('employee_id', '=', employee.id),
                ('check_out', '=', False),
            ], limit=1)

        # Today stats
        today_start = datetime.combine(fields.Date.today(), datetime.min.time())
        today_atts = request.env['hr.attendance'].sudo().search([
            ('employee_id', '=', employee.id),
            ('check_in', '>=', today_start),
            ('check_out', '!=', False),
        ])
        today_hours = sum(a.x_fclk_net_hours or 0 for a in today_atts)

        # Week stats
        today = fields.Date.today()
        week_start = today - timedelta(days=today.weekday())
        week_start_dt = datetime.combine(week_start, datetime.min.time())
        week_atts = request.env['hr.attendance'].sudo().search([
            ('employee_id', '=', employee.id),
            ('check_in', '>=', week_start_dt),
            ('check_out', '!=', False),
        ])
        week_hours = sum(a.x_fclk_net_hours or 0 for a in week_atts)

        # Recent activity
        recent = request.env['hr.attendance'].sudo().search([
            ('employee_id', '=', employee.id),
            ('check_out', '!=', False),
        ], order='check_in desc', limit=10)

        # Prepare locations JSON for JS
        locations_json = json.dumps([{
            'id': loc.id,
            'name': loc.name,
            'address': loc.address or '',
            'latitude': loc.latitude,
            'longitude': loc.longitude,
            'radius': loc.radius,
        } for loc in locations])

        values = {
            'employee': employee,
            'locations': locations,
            'is_checked_in': is_checked_in,
            'current_attendance': current_attendance,
            'today_hours': round(today_hours, 1),
            'week_hours': round(week_hours, 1),
            'recent_attendances': recent,
            'google_maps_key': google_maps_key,
            'enable_sounds': enable_sounds,
            'locations_json': locations_json,
            'page_name': 'clock',
        }
        return request.render('fusion_clock.portal_clock_page', values)

    # =========================================================================
    # Timesheet Page
    # =========================================================================

    @http.route('/my/clock/timesheets', type='http', auth='user', website=True)
    def portal_timesheets(self, period='current', **kw):
        """Read-only timesheet view."""
        employee = self._get_portal_employee()
        if not employee:
            return request.redirect('/my')

        ICP = request.env['ir.config_parameter'].sudo()
        schedule_type = ICP.get_param('fusion_clock.pay_period_type', 'biweekly')
        period_start_str = ICP.get_param('fusion_clock.pay_period_start', '')

        today = fields.Date.today()

        # Calculate period dates
        FusionReport = request.env['fusion.clock.report'].sudo()
        period_start, period_end = FusionReport._calculate_current_period(
            schedule_type, period_start_str, today
        )

        if period == 'last':
            # Go back one period
            if schedule_type == 'weekly':
                period_start -= timedelta(days=7)
                period_end -= timedelta(days=7)
            elif schedule_type == 'biweekly':
                period_start -= timedelta(days=14)
                period_end -= timedelta(days=14)
            elif schedule_type == 'monthly':
                from dateutil.relativedelta import relativedelta
                period_start -= relativedelta(months=1)
                period_end = period_start.replace(day=28) + timedelta(days=4)
                period_end -= timedelta(days=period_end.day)
            else:
                period_start -= timedelta(days=14)
                period_end -= timedelta(days=14)

        # Get attendance records
        attendances = request.env['hr.attendance'].sudo().search([
            ('employee_id', '=', employee.id),
            ('check_in', '>=', datetime.combine(period_start, datetime.min.time())),
            ('check_in', '<', datetime.combine(period_end + timedelta(days=1), datetime.min.time())),
        ], order='check_in desc')

        total_hours = sum(a.worked_hours or 0 for a in attendances if a.check_out)
        net_hours = sum(a.x_fclk_net_hours or 0 for a in attendances if a.check_out)
        total_breaks = sum(a.x_fclk_break_minutes or 0 for a in attendances if a.check_out)

        values = {
            'employee': employee,
            'attendances': attendances,
            'period_start': period_start,
            'period_end': period_end,
            'period': period,
            'schedule_type': schedule_type,
            'total_hours': round(total_hours, 1),
            'net_hours': round(net_hours, 1),
            'total_breaks': round(total_breaks, 0),
            'page_name': 'timesheets',
        }
        return request.render('fusion_clock.portal_timesheet_page', values)

    # =========================================================================
    # Reports Page
    # =========================================================================

    @http.route('/my/clock/reports', type='http', auth='user', website=True)
    def portal_reports(self, **kw):
        """View and download attendance reports."""
        employee = self._get_portal_employee()
        if not employee:
            return request.redirect('/my')

        reports = request.env['fusion.clock.report'].sudo().search([
            ('employee_id', '=', employee.id),
            ('state', 'in', ['generated', 'sent']),
        ], order='date_end desc')

        values = {
            'employee': employee,
            'reports': reports,
            'page_name': 'clock_reports',
        }
        return request.render('fusion_clock.portal_report_page', values)

    @http.route('/my/clock/reports/<int:report_id>/download', type='http', auth='user', website=True)
    def portal_report_download(self, report_id, **kw):
        """Download a specific report PDF."""
        employee = self._get_portal_employee()
        if not employee:
            return request.redirect('/my')

        report = request.env['fusion.clock.report'].sudo().browse(report_id)
        if not report.exists() or report.employee_id.id != employee.id:
            return request.redirect('/my/clock/reports')

        if not report.report_pdf:
            return request.redirect('/my/clock/reports')

        pdf_data = base64.b64decode(report.report_pdf)
        filename = report.report_pdf_filename or f"report_{report.id}.pdf"

        return request.make_response(
            pdf_data,
            headers=[
                ('Content-Type', 'application/pdf'),
                ('Content-Disposition', f'attachment; filename="{filename}"'),
            ],
        )
