<?php

namespace Modules\Employees\Controllers;

use core\Controller;
use core\Auth;
use core\Database;

class AttendanceController extends Controller
{
    public function __construct()
    {
        parent::__construct();
    }

    public function index(): void
    {
        $this->requirePermission('attendance_view');

        $db = Database::getInstance();
        $date = $this->request->get('date', date('Y-m-d'));
        $employeeId = $this->request->get('employee_id', '');
        $page = max(1, (int)$this->request->get('page', 1));
        $perPage = PAGINATION_LIMIT;

        $query = $db->table('employee_attendance a')
            ->select('a.*, e.first_name, e.last_name, e.job_title')
            ->leftJoin('employees e', 'a.employee_id', '=', 'e.id');

        if (!empty($date)) {
            $query->where('a.date', $date);
        }

        if (!empty($employeeId)) {
            $query->where('a.employee_id', $employeeId);
        }

        $attendance = $query->orderBy('a.check_in', 'DESC')
            ->paginate($perPage, $page);

        $employees = $db->table('employees')
            ->where('is_active', 1)
            ->where('deleted_at', 'IS', null)
            ->orderBy('first_name', 'ASC')
            ->get();

        $this->view('Employees/attendance', [
            'title' => 'Attendance',
            'breadcrumb' => ['Attendance' => url('attendance')],
            'attendance' => $attendance,
            'date' => $date,
            'employeeId' => $employeeId,
            'employees' => $employees,
        ]);
    }

    public function checkIn(): void
    {
        $this->requirePermission('attendance_create');

        $db = Database::getInstance();
        $employeeId = $this->request->input('employee_id', Auth::employeeId());
        $today = date('Y-m-d');
        $now = date('Y-m-d H:i:s');
        $nowTime = date('H:i:s');

        if (empty($employeeId)) {
            $this->redirectWith(url('attendance'), 'error', 'Employee not specified.');
        }

        $existing = $db->table('employee_attendance')
            ->where('employee_id', $employeeId)
            ->where('date', $today)
            ->first();

        if ($existing) {
            $this->redirectWith(url('attendance'), 'warning', 'Already checked in today.');
        }

        $schedule = $db->table('employee_schedule')
            ->where('employee_id', $employeeId)
            ->where('day_of_week', date('N'))
            ->first();

        $status = 'present';
        if ($schedule && !empty($schedule->start_time)) {
            $graceMinutes = 15;
            $lateThreshold = date('H:i:s', strtotime($schedule->start_time . ' +' . $graceMinutes . ' minutes'));
            if ($nowTime > $lateThreshold) {
                $status = 'late';
            }
        }

        $db->table('employee_attendance')->insert([
            'employee_id' => $employeeId,
            'date' => $today,
            'check_in' => $now,
            'status' => $status,
            'created_at' => date(DATE_TIME_FORMAT),
            'updated_at' => date(DATE_TIME_FORMAT),
        ]);

        $this->logActivity('check_in', 'Employee checked in: ' . $employeeId);
        $this->redirectWith(url('attendance'), 'success', 'Check-in recorded successfully.');
    }

    public function checkOut(int $id): void
    {
        $this->requirePermission('attendance_edit');

        $db = Database::getInstance();
        $record = $db->table('employee_attendance')->find($id);

        if (!$record) {
            $this->redirectWith(url('attendance'), 'error', 'Attendance record not found.');
        }

        if ($record->check_out) {
            $this->redirectWith(url('attendance'), 'warning', 'Already checked out.');
        }

        $checkIn = strtotime($record->check_in);
        $checkOut = time();
        $totalHours = round(($checkOut - $checkIn) / 3600, 2);

        $db->table('employee_attendance')
            ->where('id', $id)
            ->update([
                'check_out' => date('Y-m-d H:i:s'),
                'total_hours' => $totalHours,
                'updated_at' => date(DATE_TIME_FORMAT),
            ]);

        $this->logActivity('check_out', 'Employee checked out: ' . $record->employee_id);
        $this->redirectWith(url('attendance'), 'success', 'Check-out recorded successfully.');
    }

    public function report(): void
    {
        $this->requirePermission('attendance_view');

        $db = Database::getInstance();
        $dateFrom = $this->request->get('date_from', date('Y-m-01'));
        $dateTo = $this->request->get('date_to', date('Y-m-t'));
        $employeeId = $this->request->get('employee_id', '');

        $where = 'WHERE a.date BETWEEN :date_from AND :date_to';
        $params = [':date_from' => $dateFrom, ':date_to' => $dateTo];

        if (!empty($employeeId)) {
            $where .= ' AND a.employee_id = :employee_id';
            $params[':employee_id'] = $employeeId;
        }

        $report = $db->query(
            "SELECT
                e.id as employee_id,
                e.first_name,
                e.last_name,
                e.job_title,
                COUNT(a.id) as total_days,
                SUM(CASE WHEN a.status = 'present' THEN 1 ELSE 0 END) as present_days,
                SUM(CASE WHEN a.status = 'late' THEN 1 ELSE 0 END) as late_days,
                SUM(CASE WHEN a.status = 'absent' THEN 1 ELSE 0 END) as absent_days,
                COALESCE(SUM(a.total_hours), 0) as total_hours
             FROM employees e
             LEFT JOIN employee_attendance a ON e.id = a.employee_id {$where}
             GROUP BY e.id, e.first_name, e.last_name, e.job_title
             ORDER BY e.first_name ASC",
            $params
        );

        $employees = $db->table('employees')
            ->where('is_active', 1)
            ->where('deleted_at', 'IS', null)
            ->orderBy('first_name', 'ASC')
            ->get();

        $this->view('Employees/attendance_report', [
            'title' => 'Attendance Report',
            'breadcrumb' => [
                'Attendance' => url('attendance'),
                'Report' => url('attendance/report'),
            ],
            'report' => $report,
            'dateFrom' => $dateFrom,
            'dateTo' => $dateTo,
            'employeeId' => $employeeId,
            'employees' => $employees,
        ]);
    }
}
