<?php
declare(strict_types=1);

namespace App\Modules\HR\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\HR\Models\HrPerformanceCycle;
use App\Modules\HR\Models\HrPerformanceReview;
use App\Modules\HR\Models\HrEmployeeProfile;
use App\Modules\HR\Models\HrDepartment;
use App\Modules\HR\Services\HrNumberGenerator;

class PerformanceController extends Controller
{
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();

        $activeCycle = HrPerformanceCycle::getActiveCycle();

        $recentCycles = $db->select(
            "SELECT * FROM hr_performance_cycles WHERE is_archived = 0 ORDER BY start_date DESC LIMIT 10"
        );

        return $this->view('HR.Views.performance.index', [
            'activeCycle'  => $activeCycle,
            'recentCycles' => $recentCycles,
        ]);
    }

    public function cycles(Request $request): Response
    {
        $db = App::getInstance()->db();

        $cycles = $db->select(
            "SELECT pc.*,
                    (SELECT COUNT(*) FROM hr_performance_reviews pr WHERE pr.cycle_id = pc.id AND pr.is_archived = 0) as review_count,
                    (SELECT AVG(pr.overall_rating) FROM hr_performance_reviews pr WHERE pr.cycle_id = pc.id AND pr.is_archived = 0 AND pr.overall_rating > 0) as avg_rating
             FROM hr_performance_cycles pc
             WHERE pc.is_archived = 0
             ORDER BY pc.start_date DESC"
        );

        return $this->view('HR.Views.performance.cycles', [
            'cycles' => $cycles,
        ]);
    }

    public function createCycle(Request $request): Response
    {
        $name = trim((string) $request->post('name_ar', ''));
        $cycleType = trim((string) $request->post('period_type', 'annual'));
        $startDate = trim((string) $request->post('start_date', ''));
        $endDate = trim((string) $request->post('end_date', ''));

        $errors = [];
        if ($name === '') {
            $errors[] = 'اسم دورة التقييم مطلوب';
        }
        if ($startDate === '' || $endDate === '') {
            $errors[] = 'تاريخ البداية والنهاية مطلوبان';
        }
        if ($startDate !== '' && $endDate !== '' && $startDate >= $endDate) {
            $errors[] = 'تاريخ البداية يجب أن يكون قبل تاريخ النهاية';
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/hr/performance/cycles');
        }

        $db = App::getInstance()->db();
        $employee = $this->currentEmployee();
        $reviewDeadline = trim((string) $request->post('review_deadline', '')) ?: $endDate;
        $cycleCode = HrNumberGenerator::generateCycleCode();
        $year = (int) date('Y', strtotime($startDate));

        $cycleId = $db->insert('hr_performance_cycles', [
            'cycle_code'      => $cycleCode,
            'name_ar'         => $name,
            'year'            => $year,
            'period_type'     => $cycleType,
            'start_date'      => $startDate,
            'end_date'        => $endDate,
            'review_deadline' => $reviewDeadline,
            'status'          => 'draft',
            'created_at'      => date('Y-m-d H:i:s'),
            'updated_at'      => date('Y-m-d H:i:s'),
            'created_by'      => $employee ? (int) $employee->id : null,
        ]);

        // Auto-create review entries for all active employees
        $activeEmployees = $db->select(
            "SELECT id FROM hr_employee_profiles WHERE employment_status = 'active' AND is_archived = 0"
        );

        $reviewerId = $employee ? (int) $employee->id : 0;
        foreach ($activeEmployees as $emp) {
            $db->insert('hr_performance_reviews', [
                'cycle_id'            => $cycleId,
                'employee_profile_id' => (int) $emp['id'],
                'reviewer_id'         => $reviewerId,
                'status'              => 'pending',
                'created_at'          => date('Y-m-d H:i:s'),
                'updated_at'          => date('Y-m-d H:i:s'),
            ]);
        }

        return $this->redirect('/hr/performance/cycles/' . $cycleId)->withSuccess(
            'تم إنشاء دورة التقييم بنجاح وإضافة ' . count($activeEmployees) . ' موظف'
        );
    }

    public function showCycle(Request $request, string $id): Response
    {
        $cycle = HrPerformanceCycle::find((int) $id);
        if (!$cycle) {
            return $this->redirect('/hr/performance/cycles')->withError('دورة التقييم غير موجودة');
        }

        $reviews = HrPerformanceCycle::getReviewsForCycle((int) $id);

        $db = App::getInstance()->db();
        $stats = $db->selectOne(
            "SELECT COUNT(*) as total,
                    SUM(CASE WHEN status = 'submitted' THEN 1 ELSE 0 END) as completed,
                    SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending,
                    AVG(CASE WHEN overall_rating > 0 THEN overall_rating ELSE NULL END) as avg_rating
             FROM hr_performance_reviews
             WHERE cycle_id = ? AND is_archived = 0",
            [(int) $id]
        );

        return $this->view('HR.Views.performance.show_cycle', [
            'cycle'   => $cycle,
            'reviews' => $reviews,
            'stats'   => $stats,
        ]);
    }

    public function showReview(Request $request, string $id): Response
    {
        $review = HrPerformanceReview::find((int) $id);
        if (!$review) {
            return $this->redirect('/hr/performance')->withError('تقييم الأداء غير موجود');
        }

        $profile = HrEmployeeProfile::find((int) $review->employee_profile_id);
        $cycle = HrPerformanceCycle::find((int) $review->cycle_id);

        $db = App::getInstance()->db();
        $department = $profile->department_id
            ? $db->selectOne("SELECT name_ar FROM hr_departments WHERE id = ?", [(int) $profile->department_id])
            : null;

        $reviewer = $review->reviewer_id
            ? $db->selectOne("SELECT name FROM employees WHERE id = ?", [(int) $review->reviewer_id])
            : null;

        return $this->view('HR.Views.performance.show_review', [
            'review'     => $review,
            'profile'    => $profile,
            'cycle'      => $cycle,
            'department' => $department,
            'reviewer'   => $reviewer,
        ]);
    }

    public function editReview(Request $request, string $id): Response
    {
        $review = HrPerformanceReview::find((int) $id);
        if (!$review) {
            return $this->redirect('/hr/performance')->withError('تقييم الأداء غير موجود');
        }

        if ($review->status === 'acknowledged') {
            return $this->redirect('/hr/performance/reviews/' . $id)->withError('لا يمكن تعديل تقييم تم الإقرار به');
        }

        $profile = HrEmployeeProfile::find((int) $review->employee_profile_id);
        $cycle = HrPerformanceCycle::find((int) $review->cycle_id);

        return $this->view('HR.Views.performance.review_form', [
            'review'  => $review,
            'profile' => $profile,
            'cycle'   => $cycle,
        ]);
    }

    public function updateReview(Request $request, string $id): Response
    {
        $review = HrPerformanceReview::find((int) $id);
        if (!$review) {
            return $this->redirect('/hr/performance')->withError('تقييم الأداء غير موجود');
        }

        if ($review->status === 'acknowledged') {
            return $this->redirect('/hr/performance/reviews/' . $id)->withError('لا يمكن تعديل تقييم تم الإقرار به');
        }

        $employee = $this->currentEmployee();

        $scoresJson = $request->post('scores', []);
        $overallRating = (float) $request->post('overall_rating', 0);
        $strengths = trim((string) $request->post('strengths', '')) ?: null;
        $improvements = trim((string) $request->post('improvements', '')) ?: null;
        $goalsText = trim((string) $request->post('goals', '')) ?: null;
        $notes = trim((string) $request->post('notes', '')) ?: null;

        $errors = [];
        if ($overallRating < 1 || $overallRating > 5) {
            $errors[] = 'التقييم العام يجب أن يكون بين 1 و 5';
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/hr/performance/reviews/' . $id . '/edit');
        }

        $review->update([
            'reviewer_id'       => $employee ? (int) $employee->id : null,
            'scores_json'       => is_array($scoresJson) ? json_encode($scoresJson, JSON_UNESCAPED_UNICODE) : null,
            'overall_rating'    => $overallRating,
            'strengths'         => $strengths,
            'improvements'      => $improvements,
            'goals_json'        => $goalsText ? json_encode($goalsText, JSON_UNESCAPED_UNICODE) : null,
            'notes'             => $notes,
            'review_date'       => date('Y-m-d'),
            'status'            => 'submitted',
        ]);

        return $this->redirect('/hr/performance/reviews/' . $id)->withSuccess('تم حفظ تقييم الأداء بنجاح');
    }
}
