<?php

namespace Modules\Employees\Controllers;

use core\Controller;
use core\Auth;
use core\Database;
use core\Security;
use Modules\Employees\Models\Employee;

class EmployeeController extends Controller
{
    private Employee $employeeModel;

    public function __construct()
    {
        parent::__construct();
        $this->employeeModel = new Employee();
    }

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

        $search = $this->request->get('search', '');
        $status = $this->request->get('status', '');
        $branchId = $this->request->get('branch_id', '');
        $page = max(1, (int)$this->request->get('page', 1));
        $perPage = PAGINATION_LIMIT;
        $db = Database::getInstance();

        $query = $db->table('employees e')
            ->select('e.*, u.email as user_email')
            ->leftJoin('users u', 'e.user_id', '=', 'u.id')
            ->where('e.deleted_at', 'IS', null);

        if (!empty($search)) {
            $query->where(function ($q) use ($search) {
                $q->where('e.first_name', 'LIKE', '%' . $search . '%')
                  ->orWhere('e.last_name', 'LIKE', '%' . $search . '%')
                  ->orWhere('e.email', 'LIKE', '%' . $search . '%')
                  ->orWhere('e.phone', 'LIKE', '%' . $search . '%')
                  ->orWhere('e.mobile', 'LIKE', '%' . $search . '%');
            });
        }

        if (!empty($status)) {
            $query->where('e.is_active', $status === 'active' ? 1 : 0);
        }

        if (!empty($branchId)) {
            $query->where('e.branch_id', $branchId);
        }

        $employees = $query->orderBy('e.first_name', 'ASC')
            ->paginate($perPage, $page);

        $branches = $db->table('branches')
            ->where('deleted_at', 'IS', null)
            ->orderBy('name', 'ASC')
            ->get();

        $this->view('Employees/index', [
            'title' => 'Employees',
            'breadcrumb' => ['Employees' => url('employees')],
            'employees' => $employees,
            'search' => $search,
            'status' => $status,
            'branchId' => $branchId,
            'branches' => $branches,
        ]);
    }

    public function create(): void
    {
        $this->requirePermission('employees_create');

        $db = Database::getInstance();
        $users = $db->table('users')
            ->where('status', 'active')
            ->where('deleted_at', 'IS', null)
            ->orderBy('first_name', 'ASC')
            ->get();
        $branches = $db->table('branches')
            ->where('deleted_at', 'IS', null)
            ->orderBy('name', 'ASC')
            ->get();

        $this->view('Employees/create', [
            'title' => 'Add New Employee',
            'breadcrumb' => [
                'Employees' => url('employees'),
                'Add New' => url('employees/create'),
            ],
            'users' => $users,
            'branches' => $branches,
        ]);
    }

    public function store(): void
    {
        $this->requirePermission('employees_create');

        $validated = $this->validate([
            'first_name' => 'required|max_length:100',
            'last_name' => 'required|max_length:100',
            'email' => 'email|max_length:255',
            'phone' => 'max_length:20',
            'mobile' => 'max_length:20',
            'date_of_birth' => 'date',
            'gender' => 'in:male,female,other',
            'address' => 'max_length:500',
            'city' => 'max_length:100',
            'state' => 'max_length:100',
            'zip' => 'max_length:20',
            'job_title' => 'max_length:255',
            'hire_date' => 'date',
            'salary_type' => 'in:fixed,hourly,commission_only',
            'salary_amount' => 'numeric|min:0',
            'hourly_rate' => 'numeric|min:0',
            'commission_percent' => 'numeric|min:0|max:100',
            'target_amount' => 'numeric|min:0',
            'emergency_contact' => 'max_length:255',
            'emergency_phone' => 'max_length:20',
            'notes' => 'max_length:2000',
            'is_active' => 'in:0,1',
            'user_id' => 'integer',
            'branch_id' => 'integer',
        ]);

        if ($this->request->hasFile('photo')) {
            $file = $this->request->file('photo');
            $validation = Security::validateFile($file, ['jpg', 'jpeg', 'png', 'gif', 'webp'], UPLOAD_MAX_SIZE);
            if ($validation['valid']) {
                $path = uploadFile($file, 'employees');
                if ($path) {
                    $validated['photo'] = $path;
                }
            }
        }

        $validated['is_active'] = $validated['is_active'] ?? 1;
        $validated['user_id'] = !empty($validated['user_id']) ? (int)$validated['user_id'] : null;
        $validated['branch_id'] = !empty($validated['branch_id']) ? (int)$validated['branch_id'] : null;
        $validated['salary_amount'] = $validated['salary_amount'] ?? 0;
        $validated['hourly_rate'] = $validated['hourly_rate'] ?? 0;
        $validated['commission_percent'] = $validated['commission_percent'] ?? 0;
        $validated['target_amount'] = $validated['target_amount'] ?? 0;

        $employeeId = $this->employeeModel->create($validated);
        $this->logActivity('create', 'Created employee: ' . ($validated['first_name'] ?? '') . ' ' . ($validated['last_name'] ?? ''));
        $this->logAudit('create', 'employees', $employeeId, null, $validated);

        $this->redirectWith(url('employees'), 'success', 'Employee created successfully.');
    }

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

        $employee = $this->employeeModel->find($id);
        if (!$employee) {
            $this->redirectWith(url('employees'), 'error', 'Employee not found.');
        }

        $db = Database::getInstance();
        $users = $db->table('users')
            ->where('status', 'active')
            ->where('deleted_at', 'IS', null)
            ->orderBy('first_name', 'ASC')
            ->get();
        $branches = $db->table('branches')
            ->where('deleted_at', 'IS', null)
            ->orderBy('name', 'ASC')
            ->get();

        $this->view('Employees/edit', [
            'title' => 'Edit Employee',
            'breadcrumb' => [
                'Employees' => url('employees'),
                'Edit' => url('employees/edit/' . $id),
            ],
            'employee' => $employee,
            'users' => $users,
            'branches' => $branches,
        ]);
    }

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

        $employee = $this->employeeModel->find($id);
        if (!$employee) {
            $this->redirectWith(url('employees'), 'error', 'Employee not found.');
        }

        $oldValues = (array)$employee;

        $validated = $this->validate([
            'first_name' => 'required|max_length:100',
            'last_name' => 'required|max_length:100',
            'email' => 'email|max_length:255',
            'phone' => 'max_length:20',
            'mobile' => 'max_length:20',
            'date_of_birth' => 'date',
            'gender' => 'in:male,female,other',
            'address' => 'max_length:500',
            'city' => 'max_length:100',
            'state' => 'max_length:100',
            'zip' => 'max_length:20',
            'job_title' => 'max_length:255',
            'hire_date' => 'date',
            'salary_type' => 'in:fixed,hourly,commission_only',
            'salary_amount' => 'numeric|min:0',
            'hourly_rate' => 'numeric|min:0',
            'commission_percent' => 'numeric|min:0|max:100',
            'target_amount' => 'numeric|min:0',
            'emergency_contact' => 'max_length:255',
            'emergency_phone' => 'max_length:20',
            'notes' => 'max_length:2000',
            'is_active' => 'in:0,1',
            'user_id' => 'integer',
            'branch_id' => 'integer',
        ]);

        if ($this->request->hasFile('photo')) {
            $file = $this->request->file('photo');
            $validation = Security::validateFile($file, ['jpg', 'jpeg', 'png', 'gif', 'webp'], UPLOAD_MAX_SIZE);
            if ($validation['valid']) {
                $path = uploadFile($file, 'employees');
                if ($path) {
                    if (!empty($employee->photo)) {
                        deleteFile($employee->photo);
                    }
                    $validated['photo'] = $path;
                }
            }
        }

        $validated['is_active'] = $validated['is_active'] ?? 0;
        $validated['user_id'] = !empty($validated['user_id']) ? (int)$validated['user_id'] : null;
        $validated['branch_id'] = !empty($validated['branch_id']) ? (int)$validated['branch_id'] : null;
        $validated['salary_amount'] = $validated['salary_amount'] ?? 0;
        $validated['hourly_rate'] = $validated['hourly_rate'] ?? 0;
        $validated['commission_percent'] = $validated['commission_percent'] ?? 0;
        $validated['target_amount'] = $validated['target_amount'] ?? 0;

        $this->employeeModel->update($id, $validated);
        $this->logActivity('update', 'Updated employee: ' . ($validated['first_name'] ?? '') . ' ' . ($validated['last_name'] ?? ''));
        $this->logAudit('update', 'employees', $id, $oldValues, $validated);

        $this->redirectWith(url('employees'), 'success', 'Employee updated successfully.');
    }

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

        $db = Database::getInstance();
        $employee = $this->employeeModel->find($id);
        if (!$employee) {
            $this->redirectWith(url('employees'), 'error', 'Employee not found.');
        }

        $schedule = $db->table('employee_schedule')
            ->where('employee_id', $id)
            ->orderBy('day_of_week', 'ASC')
            ->get();

        $attendanceStats = $db->query(
            "SELECT
                COUNT(*) as total_days,
                SUM(CASE WHEN status = 'present' THEN 1 ELSE 0 END) as present_days,
                SUM(CASE WHEN status = 'late' THEN 1 ELSE 0 END) as late_days,
                SUM(CASE WHEN status = 'absent' THEN 1 ELSE 0 END) as absent_days
             FROM employee_attendance
             WHERE employee_id = :id AND MONTH(date) = MONTH(CURRENT_DATE) AND YEAR(date) = YEAR(CURRENT_DATE)",
            [':id' => $id]
        );
        $attendanceStats = $attendanceStats[0] ?? (object)['total_days' => 0, 'present_days' => 0, 'late_days' => 0, 'absent_days' => 0];

        $commissions = $db->table('employee_commissions')
            ->where('employee_id', $id)
            ->orderBy('created_at', 'DESC')
            ->limit(10)
            ->get();

        $reviews = $db->table('employee_performance')
            ->where('employee_id', $id)
            ->orderBy('created_at', 'DESC')
            ->limit(10)
            ->get();

        $this->view('Employees/show', [
            'title' => $employee->first_name . ' ' . $employee->last_name,
            'breadcrumb' => [
                'Employees' => url('employees'),
                $employee->first_name . ' ' . $employee->last_name => url('employees/show/' . $id),
            ],
            'employee' => $employee,
            'schedule' => $schedule,
            'attendanceStats' => $attendanceStats,
            'commissions' => $commissions,
            'reviews' => $reviews,
        ]);
    }

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

        $employee = $this->employeeModel->find($id);
        if (!$employee) {
            $this->redirectWith(url('employees'), 'error', 'Employee not found.');
        }

        $this->employeeModel->softDelete($id);
        $this->logActivity('delete', 'Deleted employee: ' . $employee->first_name . ' ' . $employee->last_name);
        $this->logAudit('delete', 'employees', $id, (array)$employee, null);

        $this->redirectWith(url('employees'), 'success', 'Employee deleted successfully.');
    }

    public function search(): void
    {
        $this->requirePermission('employees_view');

        $query = $this->request->get('q', '');
        $results = [];

        if (!empty($query)) {
            $results = $this->employeeModel->search($query);
        }

        $this->json([
            'success' => true,
            'data' => $results,
        ]);
    }

    public function available(): void
    {
        $this->requirePermission('employees_view');

        $date = $this->request->get('date', date('Y-m-d'));
        $time = $this->request->get('time', '');
        $serviceId = $this->request->get('service_id', '');

        $employees = $this->employeeModel->getAvailableEmployees($date, $time, $serviceId);

        $this->json([
            'success' => true,
            'data' => $employees,
        ]);
    }
}
