<?php
declare(strict_types=1);

namespace App\Modules\Inventory\Models;

use App\Core\Model;
use App\Core\App;
use App\Core\Pagination;

class Supplier extends Model
{
    protected static string $table = 'suppliers';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = true;
    protected static bool $autoTrackAuthor = true;

    protected static array $fillable = [
        'code',
        'name_ar',
        'name_en',
        'contact_person',
        'phone',
        'email',
        'address',
        'tax_number',
        'payment_terms',
        'rating',
        'is_active',
        'notes',
    ];

    /**
     * Get all active suppliers ordered by name_ar.
     */
    public static function allActive(): array
    {
        return static::query()
            ->where('is_active', '=', 1)
            ->orderBy('name_ar', 'ASC')
            ->get();
    }

    /**
     * Get supplier performance stats (orders, delivery, quality).
     */
    public static function getPerformanceStats(int $supplierId): array
    {
        $db = App::getInstance()->db();

        $row = $db->selectOne(
            "SELECT
                `total_orders`, `on_time_delivery_count`, `quality_acceptance_count`,
                `average_lead_days`, `last_order_date`
             FROM `suppliers` WHERE `id` = ?",
            [$supplierId]
        );

        $totalOrders = (int) ($row['total_orders'] ?? 0);
        $onTimeCount = (int) ($row['on_time_delivery_count'] ?? 0);
        $qualityCount = (int) ($row['quality_acceptance_count'] ?? 0);
        $avgLead = (float) ($row['average_lead_days'] ?? 0);

        return [
            'total_orders'          => $totalOrders,
            'on_time_delivery_count' => $onTimeCount,
            'quality_acceptance_count' => $qualityCount,
            'on_time_rate'          => $totalOrders > 0 ? round(($onTimeCount / $totalOrders) * 100, 1) : 0,
            'quality_rate'          => $totalOrders > 0 ? round(($qualityCount / $totalOrders) * 100, 1) : 0,
            'average_lead_days'     => round($avgLead, 1),
            'last_order_date'       => $row['last_order_date'] ?? null,
        ];
    }

    /**
     * Get outstanding AP balance for a supplier.
     */
    public static function getOutstandingBalance(int $supplierId): array
    {
        $db = App::getInstance()->db();

        $row = $db->selectOne(
            "SELECT
                COALESCE(SUM(`total_amount`), 0) as total_invoiced,
                COALESCE(SUM(`paid_amount`), 0) as total_paid,
                COALESCE(SUM(`balance`), 0) as outstanding_balance,
                COUNT(*) as invoice_count
             FROM `accounts_payable`
             WHERE `supplier_id` = ? AND `is_archived` = 0 AND `status` IN ('pending', 'partial', 'overdue')",
            [$supplierId]
        );

        return [
            'total_invoiced'      => (string) ($row['total_invoiced'] ?? '0.00'),
            'total_paid'          => (string) ($row['total_paid'] ?? '0.00'),
            'outstanding_balance' => (string) ($row['outstanding_balance'] ?? '0.00'),
            'invoice_count'       => (int) ($row['invoice_count'] ?? 0),
        ];
    }

    /**
     * Search suppliers with filters and pagination.
     */
    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $db = App::getInstance()->db();
        $where = '1=1';
        $params = [];

        if (!empty($filters['q'])) {
            $search = '%' . $filters['q'] . '%';
            $where .= ' AND (`name_ar` LIKE ? OR `code` LIKE ?)';
            $params[] = $search;
            $params[] = $search;
        }

        if (isset($filters['is_active']) && $filters['is_active'] !== '') {
            $where .= ' AND `is_active` = ?';
            $params[] = (int) $filters['is_active'];
        }

        $where .= ' AND `is_archived` = 0';

        $countRow = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM `suppliers` WHERE {$where}",
            $params
        );
        $total = (int) ($countRow['cnt'] ?? 0);
        $offset = ($page - 1) * $perPage;

        $rows = $db->select(
            "SELECT * FROM `suppliers` WHERE {$where} ORDER BY `name_ar` ASC LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        return ['data' => $rows, 'pagination' => Pagination::paginate($total, $perPage, $page)];
    }
}
