<?php
declare(strict_types=1);

namespace App\Modules\Sales\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Core\Logger;

final class CommissionService
{
    public static function registerListeners(): void
    {
        EventBus::listen('sale.completed', [self::class, 'onSaleCompleted'], 50);
    }

    public static function onSaleCompleted(array $data): void
    {
        try {
            $saleId = (int) ($data['sale_id'] ?? 0);
            if ($saleId <= 0) return;

            $db = App::getInstance()->db();
            $sale = $db->selectOne("SELECT representative_id, total_amount, sale_date FROM sales WHERE id = ?", [$saleId]);

            if (!$sale || !$sale['representative_id']) return;

            $repId = (int) $sale['representative_id'];
            $rep = $db->selectOne("SELECT * FROM sales_representatives WHERE id = ? AND is_active = 1", [$repId]);
            if (!$rep) return;

            $totalAmount = (string) $sale['total_amount'];
            $commissionAmount = '0.00';

            if ($rep['commission_type'] === 'percentage') {
                $commissionAmount = bcmul($totalAmount, bcdiv((string) $rep['commission_rate'], '100', 6), 2);
            } elseif ($rep['commission_type'] === 'fixed_per_invoice') {
                $commissionAmount = (string) $rep['commission_rate'];
            }

            if (bccomp($commissionAmount, '0', 2) <= 0) return;

            $db->insert('sales_commissions', [
                'representative_id' => $repId,
                'sale_id' => $saleId,
                'sale_amount' => $totalAmount,
                'commission_rate' => (string) $rep['commission_rate'],
                'commission_amount' => $commissionAmount,
                'commission_date' => $sale['sale_date'],
                'status' => 'pending',
                'created_at' => date('Y-m-d H:i:s'),
            ]);

            Logger::info("Commission calculated for sale #{$saleId}: {$commissionAmount}");
        } catch (\Throwable $e) {
            Logger::error('CommissionService sale.completed failed: ' . $e->getMessage());
        }
    }

    public static function getRepresentativeReport(int $repId, string $fromDate, string $toDate): array
    {
        $db = App::getInstance()->db();

        $commissions = $db->select(
            "SELECT sc.*, s.invoice_number
             FROM sales_commissions sc
             JOIN sales s ON s.id = sc.sale_id
             WHERE sc.representative_id = ? AND sc.commission_date BETWEEN ? AND ?
             ORDER BY sc.commission_date DESC",
            [$repId, $fromDate, $toDate]
        );

        $totalCommission = '0.00';
        $totalSales = '0.00';
        foreach ($commissions as $c) {
            $totalCommission = bcadd($totalCommission, (string) $c['commission_amount'], 2);
            $totalSales = bcadd($totalSales, (string) $c['sale_amount'], 2);
        }

        return [
            'commissions' => $commissions,
            'total_commission' => $totalCommission,
            'total_sales' => $totalSales,
            'count' => count($commissions),
        ];
    }

    public static function markAsPaid(array $commissionIds): int
    {
        $db = App::getInstance()->db();
        $count = 0;

        foreach ($commissionIds as $id) {
            $db->update('sales_commissions', [
                'status' => 'paid',
                'paid_at' => date('Y-m-d H:i:s'),
            ], 'id = ? AND status = ?', [(int) $id, 'pending']);
            $count++;
        }

        return $count;
    }
}
