<?php

namespace Modules\Employees\Controllers;

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

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

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

        $db = Database::getInstance();
        $employeeId = $this->request->get('employee_id', '');
        $status = $this->request->get('status', '');
        $dateFrom = $this->request->get('date_from', '');
        $dateTo = $this->request->get('date_to', '');
        $page = max(1, (int)$this->request->get('page', 1));
        $perPage = PAGINATION_LIMIT;

        $query = $db->table('employee_commissions c')
            ->select('c.*, e.first_name, e.last_name, s.name as service_name, i.invoice_number')
            ->leftJoin('employees e', 'c.employee_id', '=', 'e.id')
            ->leftJoin('services s', 'c.service_id', '=', 's.id')
            ->leftJoin('invoices i', 'c.invoice_id', '=', 'i.id');

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

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

        if (!empty($dateFrom)) {
            $query->where('c.created_at', '>=', $dateFrom . ' 00:00:00');
        }

        if (!empty($dateTo)) {
            $query->where('c.created_at', '<=', $dateTo . ' 23:59:59');
        }

        $commissions = $query->orderBy('c.created_at', 'DESC')
            ->paginate($perPage, $page);

        $totalPending = $db->table('employee_commissions')
            ->where('paid_status', 'pending')
            ->sum('commission_amount');

        $totalPaid = $db->table('employee_commissions')
            ->where('paid_status', 'paid')
            ->sum('commission_amount');

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

        $this->view('Employees/commissions', [
            'title' => 'Commissions',
            'breadcrumb' => ['Commissions' => url('commissions')],
            'commissions' => $commissions,
            'employeeId' => $employeeId,
            'status' => $status,
            'dateFrom' => $dateFrom,
            'dateTo' => $dateTo,
            'totalPending' => $totalPending,
            'totalPaid' => $totalPaid,
            'employees' => $employees,
        ]);
    }

    public function calculate(): void
    {
        $this->requirePermission('commissions_create');

        $db = Database::getInstance();
        $db->beginTransaction();

        try {
            $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 = 'i.deleted_at IS NULL AND i.status = ? AND i.created_at BETWEEN ? AND ?';
            $params = ['paid', $dateFrom . ' 00:00:00', $dateTo . ' 23:59:59'];

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

            $invoices = $db->query(
                "SELECT
                    i.id as invoice_id,
                    i.grand_total,
                    ai.employee_id,
                    ai.service_id,
                    s.commission_type,
                    s.commission_value,
                    s.name as service_name
                 FROM invoices i
                 INNER JOIN appointment_services ai ON i.appointment_id = ai.appointment_id
                 INNER JOIN services s ON ai.service_id = s.id
                 WHERE {$where}",
                $params
            );

            $calculated = 0;
            foreach ($invoices as $inv) {
                if (empty($inv->employee_id) || $inv->commission_type === 'none' || $inv->commission_value <= 0) {
                    continue;
                }

                $existing = $db->table('employee_commissions')
                    ->where('employee_id', $inv->employee_id)
                    ->where('invoice_id', $inv->invoice_id)
                    ->where('service_id', $inv->service_id)
                    ->first();

                if ($existing) {
                    continue;
                }

                $amount = match ($inv->commission_type) {
                    'percentage' => ($inv->total * $inv->commission_value) / 100,
                    'fixed' => $inv->commission_value,
                    default => 0,
                };

                if ($amount <= 0) {
                    continue;
                }

                $db->table('employee_commissions')->insert([
                    'employee_id' => $inv->employee_id,
                    'invoice_id' => $inv->invoice_id,
                    'service_id' => $inv->service_id,
                    'commission_amount' => $amount,
                    'calculated_date' => date('Y-m-d'),
                    'paid_status' => 'pending',
                    'created_at' => date(DATE_TIME_FORMAT),
                    'updated_at' => date(DATE_TIME_FORMAT),
                ]);

                $calculated++;
            }

            $db->commit();

            $this->logActivity('calculate_commissions', "Calculated {$calculated} commissions");

            $this->json([
                'success' => true,
                'message' => "{$calculated} commission(s) calculated successfully.",
                'count' => $calculated,
            ]);
        } catch (\Throwable $e) {
            $db->rollback();
            $this->error('Failed to calculate commissions: ' . $e->getMessage(), 500);
        }
    }

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

        $db = Database::getInstance();
        $commission = $db->table('employee_commissions')->find($id);

        if (!$commission) {
            $this->redirectWith(url('commissions'), 'error', 'Commission not found.');
        }

        if ($commission->paid_status === 'paid') {
            $this->redirectWith(url('commissions'), 'warning', 'Commission already paid.');
        }

        $db->table('employee_commissions')
            ->where('id', $id)
            ->update([
                'paid_status' => 'paid',
                'paid_date' => date('Y-m-d'),
                'updated_at' => date(DATE_TIME_FORMAT),
            ]);

        $this->logActivity('pay_commission', 'Paid commission #' . $id);
        $this->logAudit('update', 'employee_commissions', $id, (array)$commission, ['status' => 'paid']);

        $this->redirectWith(url('commissions'), 'success', 'Commission marked as paid.');
    }
}
