# -*- coding: utf-8 -*-
import pytz
from pytz import timezone
import collections
import datetime
from odoo import fields, models, _,api
from odoo.exceptions import ValidationError

WEEK_DAYS_AR = {
    0: "الاثنين",
    1: "الثلاثاء",
    2: "الاربعاء",
    3: "الخميس",
    4: "الجمعة",
    5: "السبت",
    6: "الاحد",
}

def hhmm(val):
    if not val:
        return "00:00"
    mins = float(val) * 60
    return "{0:02.0f}:{1:02.0f}".format(*divmod(mins, 60))

class AttendancesReport(models.TransientModel):
    _name = "employee.attendance.report"
    _description = "Employee Attendance Report"

    from_date = fields.Date(required=True)
    to_date = fields.Date(required=True)
    employee_ids = fields.Many2many("hr.employee", string="Employees", required=True)
    resource_calender_id = fields.Many2one("resource.calendar", string="Employee work record")
    type = fields.Selection([
        ("late", "Late and Early exit"),
        ("absent", "Absent"),
        ("employee", "Employee"),
    ], default="late", required=True)
    print_totals_only = fields.Boolean(string="Totals only (one line per employee)", default=False)
    shift_mode = fields.Selection(string="Shift", selection=[
        ('first', 'First'),
        ('second', 'second'),
        ('both', 'Both'),
    ], default='both', required=True)


    def _payload(self):
        return {
            "ids": self.ids,
            "model": self._name,
            "form": {
                "resource_calender_id": self.resource_calender_id.id,
                "from_date": self.from_date,
                "to_date": self.to_date,
                "employee_ids": self.employee_ids.ids,
                "type": self.type,
                "print_totals_only": self.print_totals_only,
                "shift_mode": self.shift_mode,
            },
        }

    # report_action = 'attendances.action_totals_only_attendance_report' if self.totals_only else 'attendances.action_general_attendance_report'
    # return self.env.ref(report_action).report_action(self)

    # def print_report(self):
    #     if not self.employee_ids:
    #         raise ValidationError(_("Please select Employees Name"))
    #     return self.env.ref("attendances.general_attendance_action_reportt").report_action(self, data=self._payload())

    def print_report(self):
        if not self.employee_ids:
            raise ValidationError(_("Please select Employees Name"))
        if self.print_totals_only == True:
            return self.env.ref("attendances.action_totals_only_attendance_reportt").report_action(self, data=self._payload())
        else:
            return self.env.ref("attendances.action_general_attendance_reportt").report_action(self, data=self._payload())



        # return self.env.ref(report_ref).report_action(self, data=self._payload())

    def print_excel_report(self):
        if not self.employee_ids:
            raise ValidationError(_("Please select Employees Name"))
        return self.env.ref("attendances.general_attendance_action_xls").report_action(self, data=self._payload(), config=False)

class ReportAttendancePublic(models.AbstractModel):
    _name = "report.attendances.general_attendances_report_temp"
    _description = "General Attendances Report"

    def get_value(self, data):
        type = data['form']['type']
        shift_mode = data['form']['shift_mode']
        print("ggg")
        totals_only = data["form"].get("print_totals_only", False)
        employee_ids = data['form']['employee_ids']
        resource_calender_id = data['form']['resource_calender_id']
        from_date = data['form']['from_date']
        to_date = data['form']['to_date']
        domain = [('date', '>=', from_date), ('date', '<=', to_date)]

        if resource_calender_id and not employee_ids:
            resource = self.env['resource.calendar'].browse(resource_calender_id)
            employee_ids = resource.employee_ids.ids

        if employee_ids:
            domain.append(('employee_id', 'in', list(set(employee_ids))))

        attendance_transaction_ids = self.env['hr.attendance.transaction'].search(domain)

        employee_records = attendance_transaction_ids.mapped('employee_id')
        employees = employee_records.mapped('name')

        emp_data_dict = collections.defaultdict(list)
        for emp in employee_records:
            emp_data_dict[emp.name].append({
                'job': emp.sudo().job_id.name,
                'department': emp.department_id.name,
                'emp_no': emp.emp_no,
                'emp_namw': emp.name,
            })

        if type == 'late':
            if shift_mode != 'both':
                if shift_mode == 'first':
                    attendance_transaction_ids = attendance_transaction_ids.filtered(lambda r: r.sequence == 1)
                elif shift_mode == 'second':
                    attendance_transaction_ids = attendance_transaction_ids.filtered(lambda r: r.sequence == 2)
            data = []
            final_dic = collections.defaultdict(list)
            key_list = []
            total_dic = {}
            grouped_attendance = collections.defaultdict(list)
            for resource in attendance_transaction_ids:
                grouped_attendance[resource.employee_id.name].append(resource)
                note = ''
                if resource.is_absent:
                    note = 'غياب'
                elif resource.public_holiday:
                    note = "عطلة رسمية"
                elif resource.official_id:
                    note = resource.official_id.mission_type.name
                elif resource.normal_leave:
                    note = resource.leave_id.holiday_status_id.name
                elif resource.approve_personal_permission:
                    note = resource.personal_permission_id.permission_type_id.name
                elif not resource.public_holiday and not resource.normal_leave:
                    if resource.sign_in and not resource.sign_out:
                        note = 'نسيان بصمة'
                    elif not resource.sign_in and resource.sign_out:
                        note = 'نسيان بصمة'

                data.append({
                    'date': resource.date,
                    'day': WEEK_DAYS_AR[resource.date.weekday()],
                    'sig_in': resource.sign_in,
                    'sig_out': resource.sign_out,
                    'lateness': resource.lateness,
                    'early_exit': resource.early_exit,
                    'extra_hours': resource.additional_hours,
                    'office_hours': resource.office_hours,
                    'note': note,
                    'department': resource.employee_id.department_id.name,
                    'employee_number': resource.employee_number,
                    'calendar_id': f"{resource.sequence} - {resource.calendar_id.name}" if resource.sequence else resource.calendar_id.name,
                    'employee_id': resource.employee_id,
                    'employee_name': resource.employee_id.name
                })
            data = sorted(data, key=lambda d: (d['date'], d['calendar_id']))
            for emp_name, records in grouped_attendance.items():
                total_lateness = sum(r.lateness for r in records)
                total_early_exit = sum(r.early_exit for r in records)
                total_extra_hours = sum(r.additional_hours for r in records)
                total_missing_punch = sum(
                    1 for r in records if not r.public_holiday and not r.normal_leave and
                    ((r.sign_in and not r.sign_out) or (not r.sign_in and r.sign_out))
                )
                total_absent = sum(1 for r in records if r.is_absent)
                total_not_sig_in = sum(1 for r in records if r.sign_in == 0.0)
                total_not_sig_out = sum(1 for r in records if r.sign_out == 0.0)
                total_leave = sum(1 for r in records if r.normal_leave or r.approve_personal_permission)
                total_dic[emp_name] = {'total_lateness': total_lateness, 'total_early_exit': total_early_exit,
                                  "total_extra_hours": str(datetime.timedelta(minutes=total_extra_hours)), "total_late_early": str(datetime.timedelta(minutes=total_lateness + total_early_exit)),
                                  "total_leave": total_leave, 'total_absent': total_absent,
                                  'total_not_sig_in': total_not_sig_in,
                                  'total_not_sig_out': total_not_sig_out,
                                  'total_missing_punch':total_missing_punch}

            for item in data:
                final_dic[item['employee_name']].append(item)
                key_list.append(item['employee_name'])

            mykey = list(dict.fromkeys(key_list))
            return final_dic, mykey, total_dic, dict(emp_data_dict)

        elif type == 'absent':
            data = []
            final_dic = collections.defaultdict(list)
            key_list = []
            for resource in attendance_transaction_ids.filtered(lambda r: r.is_absent == True):
                data.append({
                    'date': resource.date,
                    'employee_name': resource.employee_id.name,
                    'employee_id_department_id_name': resource.employee_id.department_id.name,
                    'day': datetime.datetime.strptime(str(resource.date), '%Y-%m-%d').date().strftime('%A'),
                })
            for item in data:
                final_dic[item['employee_id_department_id_name']].append(item)
                key_list.append(item['employee_id_department_id_name'])
            mykey = list(dict.fromkeys(key_list))
            return dict(final_dic), mykey, '', dict(emp_data_dict)
        elif type == 'employee':
            key_list = []
            total_dic = {}
            grouped_attendance = collections.defaultdict(list)
            for record in attendance_transaction_ids:
                grouped_attendance[record.employee_id.name].append(record)

            for emp_name, records in grouped_attendance.items():
                total_lateness = sum(r.lateness for r in records)
                total_early_exit = sum(r.early_exit for r in records)

                total_dic[emp_name] = {
                    'total_lateness': str(datetime.timedelta(minutes=total_lateness)),
                    'total_early_exit': str(datetime.timedelta(minutes=total_early_exit)),
                }
                key_list.append(emp_name)

            mykey = list(dict.fromkeys(key_list))
            return '', mykey, total_dic, dict(emp_data_dict)


    @api.model
    def _get_report_values(self, docids, data=None):
        final_dic, mykey, total, emp_data = self.get_value(data)
        start_date = data['form']['from_date']
        end_date = data['form']['to_date']
        type_ = data['form']['type']
        shift_mode = data['form']['shift_mode']
        totals_only = data['form'].get('print_totals_only', False)

        summary_rows = []
        summary_totals = []
        if totals_only:
            domain = [('date', '>=', start_date), ('date', '<=', end_date)]
            emp_ids = data['form']['employee_ids']
            cal_id = data['form']['resource_calender_id']
            if emp_ids:
                domain.append(('employee_id', 'in', list(set(emp_ids))))
            elif cal_id:
                rc = self.env['resource.calendar'].browse(cal_id)
                domain.append(('employee_id', 'in', rc.employee_ids.ids))

            att = self.env['hr.attendance.transaction'].search(domain)
            if shift_mode != 'both':
                if shift_mode == 'first':
                    att = att.filtered(lambda r: r.sequence == 1)
                elif shift_mode == 'second':
                    att = att.filtered(lambda r: r.sequence == 2)
            for emp in att.mapped('employee_id'):
                # lines = att.filtered(lambda l, e=emp: l.employee_id == e)

                emp_att_lines = att.filtered(lambda l: l.employee_id == emp)
                for seq in sorted(set(emp_att_lines.mapped('sequence'))):  # For each shift (1, 2)
                    lines = emp_att_lines.filtered(lambda l: l.sequence == seq)

                    all_days = {l.date for l in lines}
                    absent = {l.date for l in lines if l.is_absent}
                    vacation = {l.date for l in lines if l.normal_leave}

                    holidays = {l.date for l in lines if l.public_holiday}

                    iq = getattr(emp, 'iqama_number', False) or getattr(emp, 'saudi_number', '')
                    calendar_name = lines[0].calendar_id.name if lines and lines[0].calendar_id else ''
                    summary_rows.append({
                        'employee_number': emp.emp_no or '',
                        'name': emp.name,
                        'seq': f"{seq} - {calendar_name}" if seq else '',
                        'iqama': iq.display_name or '',
                        'department': emp.department_id.name,
                        'job': emp.sudo().job_id.name,
                        'days_present': len(all_days - absent - vacation - holidays),
                        'leave_days': len(vacation),
                        'holiday_days': len(holidays),
                        'absent_days': len(absent),

                        'office_hours': hhmm(sum(lines.mapped('office_hours'))),
                        'extra_hours': hhmm(sum(lines.mapped('additional_hours'))),
                        'permission_hours': hhmm(sum(lines.mapped('total_permission_hours'))),
                        'mission_hours': hhmm(sum(lines.mapped('total_mission_hours'))),
                        'lateness_approved': hhmm(sum(lines.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
                        'early_exit_approved': hhmm(sum(lines.filtered(lambda l: l.approve_exit_out).mapped('early_exit'))),

                        'office_hours_int': (sum(lines.mapped('office_hours'))),
                        'extra_hours_int': (sum(lines.mapped('additional_hours'))),
                        'permission_hours_int': (sum(lines.mapped('total_permission_hours'))),
                        'mission_hours_int': (sum(lines.mapped('total_mission_hours'))),
                        'lateness_approved_int': (sum(lines.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
                        'early_exit_approved_int': (sum(lines.filtered(lambda l: l.approve_exit_out).mapped('early_exit'))),

                    })

            summary_totals.append({
                'days_present': sum(row['days_present'] for row in summary_rows),
                'leave_days': sum(row['leave_days'] for row in summary_rows),
                'holiday_days': sum(row['holiday_days'] for row in summary_rows),
                'absent_days': sum(row['absent_days'] for row in summary_rows),

                'office_hours': hhmm(sum(row['office_hours_int'] for row in summary_rows)),
                'extra_hours': hhmm(sum(row['extra_hours_int'] for row in summary_rows)),
                'permission_hours': hhmm(sum(row['permission_hours_int'] for row in summary_rows)),
                'mission_hours': hhmm(sum(row['mission_hours_int'] for row in summary_rows)),
                'lateness_approved':hhmm( sum(row['lateness_approved_int'] for row in summary_rows)),
                'early_exit_approved': hhmm(sum(row['early_exit_approved_int'] for row in summary_rows)),
            })

        return {
            'doc_ids': data['ids'],
            'doc_model': data['model'],
            'date_start': start_date,
            'date_end': end_date,
            'type': type_,
            'data': final_dic,
            'mykey': mykey,
            'emp_data': emp_data,
            'total': total,
            'summary': summary_rows,
            'summary_totals': summary_totals,
            'totals_only': totals_only,
            'print_date': fields.Datetime.now().strftime("%H:%M %m/%d/%Y"),
            'print_user': self.env.user.name,
        }



class ReportAttendancegeneral(models.AbstractModel):
    _name = "report.attendances.general_attendances_report_temp_land"
    _description = "General Attendances Report"

    def get_value(self, data):
        type = data['form']['type']
        shift_mode = data['form']['shift_mode']
        totals_only = data["form"].get("print_totals_only", False)
        employee_ids = data['form']['employee_ids']
        resource_calender_id = data['form']['resource_calender_id']
        from_date = data['form']['from_date']
        to_date = data['form']['to_date']
        domain = [('date', '>=', from_date), ('date', '<=', to_date)]

        if resource_calender_id and not employee_ids:
            resource = self.env['resource.calendar'].browse(resource_calender_id)
            employee_ids = resource.employee_ids.ids

        if employee_ids:
            domain.append(('employee_id', 'in', list(set(employee_ids))))

        attendance_transaction_ids = self.env['hr.attendance.transaction'].search(domain)
        employee_records = attendance_transaction_ids.mapped('employee_id')
        employees = employee_records.mapped('name')

        emp_data_dict = collections.defaultdict(list)
        for emp in employee_records:
            emp_data_dict[emp.name].append({
                'job': emp.sudo().job_id.name,
                'department': emp.department_id.name,
                'emp_no': emp.emp_no,
                'emp_namw': emp.name,
            })

        if type == 'late':
            if shift_mode != 'both':
                if shift_mode == 'first':
                    attendance_transaction_ids = attendance_transaction_ids.filtered(lambda r: r.sequence == 1)
                elif shift_mode == 'second':
                    attendance_transaction_ids = attendance_transaction_ids.filtered(lambda r: r.sequence == 2)
            data = []
            final_dic = collections.defaultdict(list)
            total_dic = {}
            key_list = []
            grouped_attendance = collections.defaultdict(list)
            for resource in attendance_transaction_ids:
                grouped_attendance[resource.employee_id.name].append(resource)
                note = ''
                if resource.is_absent:
                    note = 'غياب'
                elif resource.public_holiday:
                    note = "عطلة رسمية"
                elif resource.official_id:
                    note = resource.official_id.mission_type.name
                elif resource.normal_leave:
                    note = resource.leave_id.holiday_status_id.name
                elif resource.approve_personal_permission:
                    note = resource.personal_permission_id.permission_type_id.name
                elif not resource.public_holiday and not resource.normal_leave:
                    if resource.sign_in and not resource.sign_out:
                        note = 'نسيان بصمة'
                    elif not resource.sign_in and resource.sign_out:
                        note = 'نسيان بصمة'

                data.append({
                    'date': resource.date,
                    'day': WEEK_DAYS_AR[resource.date.weekday()],
                    'sig_in': resource.sign_in,
                    'sig_out': resource.sign_out,
                    'lateness': resource.lateness,
                    'early_exit': resource.early_exit,
                    'extra_hours': resource.additional_hours,
                    'office_hours': resource.office_hours,
                    'note': note,
                    'department': resource.employee_id.department_id.name,
                    'employee_number': resource.employee_number,
                    'calendar_id': resource.calendar_id.name,
                    'employee_id': resource.employee_id,
                    'employee_name': resource.employee_id.name,
                })

            data = sorted(data, key=lambda d: d['date'])
            for emp_name, recs in grouped_attendance.items():
                total_lateness = sum(r.lateness for r in recs)
                total_early_exit = sum(r.early_exit for r in recs)
                total_extra_hours = sum(r.additional_hours for r in recs)
                total_missing_punch = sum(
                    1 for r in recs if not r.public_holiday and not r.normal_leave and (
                        (r.sign_in and not r.sign_out) or (not r.sign_in and r.sign_out))
                )
                total_absent = sum(1 for r in recs if r.is_absent)
                total_not_sig_in = sum(1 for r in recs if r.sign_in == 0.0)
                total_not_sig_out = sum(1 for r in recs if r.sign_out == 0.0)
                total_leave = sum(1 for r in recs if r.normal_leave or r.approve_personal_permission)
                total_dic[emp_name] = {'total_lateness': total_lateness, 'total_early_exit': total_early_exit,
                                  "total_extra_hours": str(datetime.timedelta(minutes=total_extra_hours)), "total_late_early": str(datetime.timedelta(minutes=total_lateness + total_early_exit)),
                                  "total_leave": total_leave, 'total_absent': total_absent,
                                  'total_not_sig_in': total_not_sig_in,
                                  'total_not_sig_out': total_not_sig_out,
                                  'total_missing_punch':total_missing_punch}

            for item in data:
                final_dic[item['employee_name']].append(item)
                key_list.append(item['employee_name'])

            mykey = list(dict.fromkeys(key_list))
            return final_dic, mykey, total_dic, dict(emp_data_dict)

        elif type == 'absent':
            data = []
            grouped = collections.defaultdict(list)
            key_list = []

            for resource in attendance_transaction_ids.filtered(lambda r: r.is_absent == True):
                data.append({
                    'date': resource.date,
                    'employee_name': resource.employee_id.name,
                    'employee_id_department_id_name': resource.employee_id.department_id.name,
                    'day': datetime.datetime.strptime(str(resource.date), '%Y-%m-%d').date().strftime('%A'),
                })

            for item in data:
                grouped[item['employee_id_department_id_name']].append(item)
                key_list.append(item['employee_id_department_id_name'])

            mykey = list(dict.fromkeys(key_list))
            return dict(grouped), mykey, '', dict(emp_data_dict)
        elif type == 'employee':
            grouped_attendance = collections.defaultdict(list)
            key_list = []
            total_dic = {}
            for rec in attendance_transaction_ids:
                grouped_attendance[rec.employee_id.name].append(rec)
            for emp_name, recs in grouped_attendance.items():
                total_lateness = sum(r.lateness for r in recs)
                total_early_exit = sum(r.early_exit for r in recs)
                total_dic[emp_name] = {
                    'total_lateness': str(datetime.timedelta(minutes=total_lateness)),
                    'total_early_exit': str(datetime.timedelta(minutes=total_early_exit)),
                }
                key_list.append(emp_name)

            mykey = list(dict.fromkeys(key_list))
            return '', mykey, total_dic, dict(emp_data_dict)


    @api.model
    def _get_report_values(self, docids, data=None):
        final_dic, mykey, total, emp_data = self.get_value(data)
        start_date = data['form']['from_date']
        end_date = data['form']['to_date']
        type_ = data['form']['type']
        shift_mode = data['form']['shift_mode']
        totals_only = data['form'].get('print_totals_only', False)

        summary_rows = []
        summary_totals = []
        if totals_only:
            domain = [('date', '>=', start_date), ('date', '<=', end_date)]
            emp_ids = data['form']['employee_ids']
            cal_id = data['form']['resource_calender_id']
            if emp_ids:
                domain.append(('employee_id', 'in', list(set(emp_ids))))
            elif cal_id:
                rc = self.env['resource.calendar'].browse(cal_id)
                domain.append(('employee_id', 'in', rc.employee_ids.ids))

            att = self.env['hr.attendance.transaction'].search(domain)
            if shift_mode != 'both':
                if shift_mode == 'first':
                    att = att.filtered(lambda r: r.sequence == 1)
                elif shift_mode == 'second':
                    att = att.filtered(lambda r: r.sequence == 2)
            for emp in att.mapped('employee_id'):
                # lines = att.filtered(lambda l, e=emp: l.employee_id == e)

                emp_att_lines = att.filtered(lambda l: l.employee_id == emp)
                for seq in sorted(set(emp_att_lines.mapped('sequence'))):  # For each shift (1, 2)
                    lines = emp_att_lines.filtered(lambda l: l.sequence == seq)

                    all_days = {l.date for l in lines}
                    absent = {l.date for l in lines if l.is_absent}
                    vacation = {l.date for l in lines if l.normal_leave}
                    holidays = {l.date for l in lines if l.public_holiday}
                    missing_punch = {l.date for l in lines if
                                     not l.public_holiday and
                                     not l.normal_leave and
                                     ((l.sign_in and not l.sign_out) or (not l.sign_in and l.sign_out))}

                    iq = getattr(emp, 'iqama_number', False) or getattr(emp, 'saudi_number', '')
                    calendar_name = lines[0].calendar_id.name if lines and lines[0].calendar_id else ''
                    summary_rows.append({
                        'employee_number': emp.emp_no or '',
                        'name': emp.name,
                        'seq': f"{seq} - {calendar_name}" if seq else '',
                        'iqama': iq.display_name or '',
                        'department': emp.department_id.name,
                        'job': emp.sudo().job_id.name,
                        'days_present': len(all_days - absent - vacation - holidays),
                        'leave_days': len(vacation),
                        'holiday_days': len(holidays),
                        'absent_days': len(absent),
                        'missing_punch_days': len(missing_punch),
                        'office_hours': hhmm(sum(lines.mapped('office_hours'))),
                        'extra_hours': hhmm(sum(lines.mapped('additional_hours'))),
                        'permission_hours': hhmm(sum(lines.mapped('total_permission_hours'))),
                        'mission_hours': hhmm(sum(lines.mapped('total_mission_hours'))),
                        'lateness_approved': hhmm(sum(lines.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
                        'early_exit_approved': hhmm(sum(lines.filtered(lambda l: l.approve_exit_out).mapped('early_exit'))),

                        'office_hours_int': (sum(lines.mapped('office_hours'))),
                        'extra_hours_int': (sum(lines.mapped('additional_hours'))),
                        'permission_hours_int': (sum(lines.mapped('total_permission_hours'))),
                        'mission_hours_int': (sum(lines.mapped('total_mission_hours'))),
                        'lateness_approved_int': (sum(lines.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
                        'early_exit_approved_int': (sum(lines.filtered(lambda l: l.approve_exit_out).mapped('early_exit'))),

                    })

            summary_totals.append({
                'days_present': sum(row['days_present'] for row in summary_rows),
                'leave_days': sum(row['leave_days'] for row in summary_rows),
                'holiday_days': sum(row['holiday_days'] for row in summary_rows),
                'absent_days': sum(row['absent_days'] for row in summary_rows),
                'missing_punch_days': sum(row['missing_punch_days'] for row in summary_rows),
                'office_hours': hhmm(sum(row['office_hours_int'] for row in summary_rows)),
                'extra_hours': hhmm(sum(row['extra_hours_int'] for row in summary_rows)),
                'permission_hours': hhmm(sum(row['permission_hours_int'] for row in summary_rows)),
                'mission_hours': hhmm(sum(row['mission_hours_int'] for row in summary_rows)),
                'lateness_approved':hhmm( sum(row['lateness_approved_int'] for row in summary_rows)),
                'early_exit_approved': hhmm(sum(row['early_exit_approved_int'] for row in summary_rows)),
            })


        return {
            'doc_ids': data['ids'],
            'doc_model': data['model'],
            'date_start': start_date,
            'date_end': end_date,
            'type': type_,
            'data': final_dic,
            'mykey': mykey,
            'emp_data': emp_data,
            'total': total,
            'summary': summary_rows,
            'summary_totals': summary_totals,
            'totals_only': totals_only,
            'print_date': fields.Datetime.now().strftime("%H:%M %m/%d/%Y"),
            'print_user': self.env.user.name,
        }


class AttendancesReportXls(models.AbstractModel):
    _name = 'report.attendances.general_attendance_xls'
    _inherit = 'report.report_xlsx.abstract'

    def generate_xlsx_report(self, workbook, data, objs):
        self = self.with_context(lang=self.env.user.lang)
        x = self.env['report.attendances.general_attendances_report_temp']
        final_dic, mykey, total, emp_data = ReportAttendancePublic.get_value(x, data)
        start_date = data['form']['from_date']
        end_date = data['form']['to_date']
        type = data['form']['type']
        totals_only = data['form'].get('print_totals_only', False)
        sheet = workbook.add_worksheet(U'Holiday Report')
        calendar_id = data['form']['resource_calender_id']
        sheet.right_to_left()
        sheet.set_column(1, 10, 15)
        employee_ids = data['form']['employee_ids']
        format2 = workbook.add_format(
            {'font_size': 10, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center',
             'bold': True})
        format2.set_align('center')
        format2.set_align('vcenter')
        fmt = workbook.add_format({'font_size': 10, 'border': 1, 'align': 'center', 'valign': 'vcenter', 'bold': True})

        # if totals_only:
        #     sheet.merge_range('F2:P2', _('تقرير الحضور والانصراف للموظفين'), fmt)
        #     sheet.write('G3', _('من تاريخ'), fmt)
        #     sheet.write('J3', _('إلى تاريخ'), fmt)
        #     sheet.write(2, 7, str(start_date), fmt)
        #     sheet.write(2, 10, str(end_date), fmt)
        #
        #     headers = [
        #         'الرقم الوظيفي', 'اسم الموظف', 'رقم الهوية', 'اﻹدارة', 'المسمي الوظيفي',
        #         'ايام الحضور', 'الاجازات', 'الاجازات الرسمية', 'الغياب', 'ساعات العمل الفعلية',
        #         'ساعات العمل الاضافية', 'الاستئذان', 'مهام عمل/انتداب/تدريب', 'التأخيرات', 'الخروج المبكر',
        #     ]
        #     for col, h in enumerate(headers, start=1):
        #         sheet.write(5, col, h, fmt)
        #
        #     domain = [('date', '>=', start_date), ('date', '<=', end_date)]
        #     emp_ids = data['form']['employee_ids']
        #     cal_id = data['form']['resource_calender_id']
        #     if emp_ids:
        #         domain.append(('employee_id', 'in', list(set(emp_ids))))
        #     elif cal_id:
        #         rc = self.env['resource.calendar'].browse(cal_id)
        #         domain.append(('employee_id', 'in', rc.employee_ids.ids))
        #     att = self.env['hr.attendance.transaction'].search(domain)
        #
        #     row = 6
        #     total_days = 0
        #     total_leave = 0
        #     total_holidays = 0
        #     total_absent = 0
        #     for emp in att.mapped('employee_id'):
        #         lines = att.filtered(lambda l, e=emp: l.employee_id == e)
        #
        #         all_days = {l.date for l in lines}
        #         absent = {l.date for l in lines if l.is_absent}
        #         vacation = {l.date for l in lines if l.normal_leave}
        #         holidays = {l.date for l in lines if l.public_holiday}
        #         total_days +=  len(all_days - absent - vacation - holidays)
        #         total_leave += len(vacation)
        #         total_holidays += len(holidays)
        #         total_absent += len(absent)
        #
        #         iq = getattr(emp, 'iqama_number', False) or getattr(emp, 'saudi_number', '')
        #
        #         sheet.write_row(row, 1, [
        #             emp.emp_no or '', emp.name, iq.display_name,
        #             emp.department_id.name, emp.sudo().job_id.name,
        #             len(all_days - absent - vacation - holidays),
        #             len(vacation), len(holidays), len(absent),
        #             hhmm(sum(lines.mapped('office_hours'))),
        #             hhmm(sum(lines.mapped('additional_hours'))),
        #             hhmm(sum(lines.mapped('total_permission_hours'))),
        #             hhmm(sum(lines.mapped('total_mission_hours'))),
        #             hhmm(sum(lines.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
        #             hhmm(sum(lines.filtered(lambda l: l.approve_exit_out).mapped('early_exit')))
        #         ], fmt)
        #         row += 1
        #
        #     sheet.write_row(row, 1, [
        #         _('الاجمالي'), '', '', '', '',
        #         total_days,
        #         total_leave,
        #         total_holidays,
        #         total_absent,
        #         hhmm(sum(att.mapped('office_hours'))),
        #         hhmm(sum(att.mapped('additional_hours'))),
        #         hhmm(sum(att.mapped('total_permission_hours'))),
        #         hhmm(sum(att.mapped('total_mission_hours'))),
        #         hhmm(sum(att.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
        #         hhmm(sum(att.filtered(lambda l: l.approve_exit_out).mapped('early_exit')))
        #     ], fmt)
        #     return

        if totals_only:

            sheet.merge_range('F2:P2', _('تقرير الحضور والانصراف للموظفين'), fmt)
            sheet.write('G3', _('من تاريخ'), fmt)
            sheet.write('J3', _('إلى تاريخ'), fmt)
            sheet.write(2, 7, str(start_date), fmt)
            sheet.write(2, 10, str(end_date), fmt)

            headers = [
                'الرقم الوظيفي', 'اسم الموظف', 'الدوام', 'رقم الهوية', 'اﻹدارة', 'المسمي الوظيفي',
                'ايام الحضور', 'الاجازات', 'الاجازات الرسمية', 'الغياب', 'نسيان البصمة',
                'ساعات العمل الفعلية', 'ساعات العمل الاضافية', 'الاستئذان', 'مهام عمل/انتداب/تدريب',
                'التأخيرات', 'الخروج المبكر',
            ]

            for col, h in enumerate(headers, start=1):
                sheet.write(5, col, h, fmt)

            domain = [('date', '>=', start_date), ('date', '<=', end_date)]
            emp_ids = data['form']['employee_ids']
            cal_id = data['form']['resource_calender_id']
            if emp_ids:
                domain.append(('employee_id', 'in', list(set(emp_ids))))
            elif cal_id:
                rc = self.env['resource.calendar'].browse(cal_id)
                domain.append(('employee_id', 'in', rc.employee_ids.ids))
            att = self.env['hr.attendance.transaction'].search(domain)

            row = 6
            total_days = 0
            total_leave = 0
            total_holidays = 0
            total_absent = 0
            total_missing_punch = 0
            for emp in att.mapped('employee_id'):
                emp_att_lines = att.filtered(lambda l: l.employee_id == emp)
                for seq in sorted(set(emp_att_lines.mapped('sequence'))):  # For each shift (1, 2)
                    lines = emp_att_lines.filtered(lambda l: l.sequence == seq)

                    all_days = {l.date for l in lines}
                    absent = {l.date for l in lines if l.is_absent}
                    vacation = {l.date for l in lines if l.normal_leave}
                    holidays = {l.date for l in lines if l.public_holiday}
                    missing_punch = {l.date for l in lines if
                                     not l.public_holiday and
                                     not l.normal_leave and
                                     ((l.sign_in and not l.sign_out) or (not l.sign_in and l.sign_out))}

                    total_days += len(all_days - absent - vacation - holidays)
                    total_leave += len(vacation)
                    total_holidays += len(holidays)
                    total_absent += len(absent)
                    total_missing_punch += len(missing_punch)
                    iq = getattr(emp, 'iqama_number', False) or getattr(emp, 'saudi_number', '')
                    calendar_name = lines[0].calendar_id.name if lines and lines[0].calendar_id else ''

                    sheet.write_row(row, 1, [
                        emp.emp_no or '',
                        emp.name,
                        f"{seq} - {calendar_name}" if seq else '',
                        iq.display_name,
                        emp.department_id.name,

                        emp.sudo().job_id.name,
                        len(all_days - absent - vacation - holidays),
                        len(vacation),
                        len(holidays),
                        len(absent),
                        len(missing_punch),
                        hhmm(sum(lines.mapped('office_hours'))),
                        hhmm(sum(lines.mapped('additional_hours'))),
                        hhmm(sum(lines.mapped('total_permission_hours'))),
                        hhmm(sum(lines.mapped('total_mission_hours'))),
                        hhmm(sum(lines.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
                        hhmm(sum(lines.filtered(lambda l: l.approve_exit_out).mapped('early_exit')))
                    ], fmt)
                    row += 1

            # Totals row
            sheet.write_row(row, 1, [
                _('الاجمالي'), '', '', '', '','',
                total_days,
                total_leave,
                total_holidays,
                total_absent,
                total_missing_punch,
                hhmm(sum(att.mapped('office_hours'))),
                hhmm(sum(att.mapped('additional_hours'))),
                hhmm(sum(att.mapped('total_permission_hours'))),
                hhmm(sum(att.mapped('total_mission_hours'))),
                hhmm(sum(att.filtered(lambda l: l.approve_lateness).mapped('lateness'))),
                hhmm(sum(att.filtered(lambda l: l.approve_exit_out).mapped('early_exit')))
            ], fmt)

            return

        if type == 'late':
            sheet.merge_range('D3:I3', _("Attendance Reports"), format2)
            sheet.write('E4:E4', _("From date"), format2)
            sheet.write('G4:G4', _("To date"), format2)
            sheet.write(3, 5, str(start_date)[0:10], format2)
            sheet.write(3, 7, str(end_date)[0:10], format2)
            row = 9
            for key in mykey:
                n = 1
                h_col = 4
                size = len(final_dic[key])
                tot_size = len(total[key])
                sheet.write(row - 3, h_col, _('Employee Number'), format2)
                sheet.write(row - 3, h_col + 3, _('job '), format2)
                sheet.write(row - 2, h_col, _('Name'), format2)
                sheet.write(row - 2, h_col + 3, _('Department'), format2)

                sheet.write(row, n, _('date'), format2)
                sheet.write(row, n + 1, _('day'), format2)
                sheet.write(row, n + 2, _('Sign in'), format2)
                sheet.write(row, n + 3, _('Sign out'), format2)
                sheet.write(row, n + 4, _('lateness'), format2)
                sheet.write(row, n + 5, _('Early Exit'), format2)
                sheet.write(row, n + 6, _('Extra hours'), format2)
                sheet.write(row, n + 7, _('Office Hours'), format2)
                sheet.write(row, n + 8, _('Notes'), format2)
                sheet.write(row, n + 9, _('Shift'), format2)
                data_row = row + 1
                total_lateness = total_early_exit = total_extra_hours = total_office_hours = 0.0

                for line in final_dic[key]:
                    sheet.merge_range(row - 3, h_col + 1, row - 3, h_col + 2, emp_data[key][0]['emp_no'], format2)
                    sheet.write(row - 3, h_col + 4, emp_data[key][0]['job'], format2)
                    sheet.merge_range(row - 2, h_col + 1, row - 2, h_col + 2, emp_data[key][0]['emp_namw'], format2)
                    sheet.write(row - 2, h_col + 4, emp_data[key][0]['department'], format2)
                    sheet.write(data_row, n, str(line['date']), format2)
                    sheet.write(data_row, n + 1, str(line['day']), format2)

                    sheet.write(data_row, n + 2, '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['sig_in']) * 60, 60)),
                                format2)
                    sheet.write(data_row, n + 3, '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['sig_out']) * 60, 60)),
                                format2)
                    sheet.write(data_row, n + 4,
                                '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['lateness']) * 60, 60)), format2)
                    sheet.write(data_row, n + 5,
                                '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['early_exit']) * 60, 60)), format2)
                    sheet.write(data_row, n + 6,
                                '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['extra_hours']) * 60, 60)), format2)
                    sheet.write(data_row, n + 7,
                                '{0:02.0f}:{1:02.0f}'.format(*divmod(float(line['office_hours']) * 60, 60)), format2)

                    sheet.write(data_row, n + 8, line['note'], format2)
                    sheet.write(data_row, n + 9, line['calendar_id'], format2)
                    total_lateness += float(line['lateness'])
                    total_early_exit += float(line['early_exit'])
                    total_extra_hours += float(line['extra_hours'])
                    total_office_hours += float(line['office_hours'])
                    data_row += 1

                sheet.write(data_row + 1, n + 3, _('الاجمالي'), format2)
                sheet.write(data_row + 1, n + 4, '{0:02.0f}:{1:02.0f}'.format(*divmod(total_lateness * 60, 60)),
                            format2)
                sheet.write(data_row + 1, n + 5, '{0:02.0f}:{1:02.0f}'.format(*divmod(total_early_exit * 60, 60)),
                            format2)
                sheet.write(data_row + 1, n + 6, '{0:02.0f}:{1:02.0f}'.format(*divmod(total_extra_hours * 60, 60)),
                            format2)
                sheet.write(data_row + 1, n + 7, '{0:02.0f}:{1:02.0f}'.format(*divmod(total_office_hours * 60, 60)),
                            format2)

                sheet.write(data_row + 3, n + 4, _('Total lateness'), format2)
                # sheet.set_column(data_row,data_row, 15)
                sheet.write(data_row + 3, n + 5, str(total[key]['total_late_early'].split('.')[0]), format2)
                sheet.write(data_row + 3, n + 6, _('Total Absent'), format2)
                sheet.write(data_row + 3, n + 7, str(total[key]['total_absent']), format2)
                size -= 2
                sheet.write(data_row + 4, n + 4, _('Total Extra'), format2)
                sheet.write(data_row + 4, n + 5, str(total[key]['total_extra_hours'].split('.')[0]), format2)
                sheet.write(data_row + 4, n + 6, _('Total Leave'), format2)
                sheet.write(data_row + 4, n + 7, total[key]['total_leave'], format2)
                n += 1
                data_row += 5
                row += size + 3 + tot_size
                row += 1

                print("kkkkkkggggggggggg")
        elif type == 'absent':
            sheet.merge_range('C3:G3', _("Absent Report"), format2)
            sheet.merge_range('C4:G4', _("All Employee - Details"), format2)
            sheet.merge_range('B5:C5', _("From date"), format2)
            sheet.merge_range('F5:G5', _("To date"), format2)
            sheet.write(4, 3, str(start_date)[0:10], format2)
            sheet.write(4, 7, str(end_date)[0:10], format2)
            row = 8
            for key in mykey:
                n = 1
                size = len(final_dic[key])
                sheet.write(row - 2, n, _('Department'), format2)
                sheet.write(row, n, _('Employee Name'), format2)
                sheet.write(row, n + 1, _('Day'), format2)
                sheet.write(row, n + 2, _('date'), format2)
                sheet.write(row, n + 3, _('Notes'), format2)
                data_row = row + 1
                for line in final_dic[key]:
                    sheet.write(row - 2, n + 1, line['employee_id_department_id_name'], format2)
                    sheet.write(data_row, n, line['employee_name'], format2)
                    sheet.write(data_row, n + 1, line['day'], format2)
                    sheet.write(data_row, n + 2, line['date'], format2)
                    sheet.write(data_row, n + 3, (' '), format2)
                    data_row += 1
                n += 1
                row += size + 3
                row += 1

        elif type == 'employee':
            sheet.merge_range('C3:G3', _("Employee Attendance Report"), format2)
            sheet.merge_range('B4:C4', _("From date"), format2)
            sheet.merge_range('F4:G4', _("To date"), format2)
            sheet.write(3, 3, str(start_date)[0:10], format2)
            sheet.write(3, 7, str(end_date)[0:10], format2)
            row = 8
            for key in mykey:
                n = 1
                size = len(total[key])
                sheet.write(row, n, _('Employee Name'), format2)
                sheet.write(row, n + 1, _('Total of Lateness '), format2)
                sheet.write(row, n + 2, _('Total of Early Exit'), format2)
                data_row = row + 1
                sheet.write(data_row, n, key, format2)
                sheet.write(data_row, n + 1, total[key]['total_lateness'], format2)
                sheet.write(data_row, n + 2, total[key]['total_early_exit'], format2)
                data_row += 1
                n += 1
                row += size + 1
                row += 1

