<?php
declare(strict_types=1);

namespace App\Modules\Receipts\Models;

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

class Receipt
{
    public static function find(int $id): ?array
    {
        $db = App::getInstance()->db();
        return $db->selectOne("SELECT * FROM receipts WHERE id = ?", [$id]);
    }

    public static function findWithDetails(int $id): ?array
    {
        $db = App::getInstance()->db();
        return $db->selectOne(
            "SELECT r.*, m.full_name_ar as member_name, m.membership_number, m.phone_mobile,
                    e.full_name_ar as issued_by_name, ve.full_name_ar as voided_by_name,
                    p.payment_type, p.payment_method
             FROM receipts r
             JOIN members m ON m.id = r.member_id
             LEFT JOIN employees e ON e.id = r.issued_by_employee_id
             LEFT JOIN employees ve ON ve.id = r.voided_by
             LEFT JOIN payments p ON p.id = r.payment_id
             WHERE r.id = ?",
            [$id]
        );
    }

    public static function generateNumber(): string
    {
        $db = App::getInstance()->db();
        $year = date('Y');
        $prefix = 'REC-' . $year . '-';
        $last = $db->selectOne(
            "SELECT receipt_number FROM receipts WHERE receipt_number LIKE ? ORDER BY id DESC LIMIT 1",
            [$prefix . '%']
        );
        if ($last) {
            $parts = explode('-', $last['receipt_number']);
            $seq = (int) end($parts) + 1;
        } else {
            $seq = 1;
        }
        return $prefix . str_pad((string) $seq, 6, '0', STR_PAD_LEFT);
    }

    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $db = App::getInstance()->db();
        $where = '1=1';
        $params = [];

        if (isset($filters['is_voided']) && $filters['is_voided'] !== '') {
            $where .= ' AND r.is_voided = ?';
            $params[] = (int) $filters['is_voided'];
        }
        if (!empty($filters['date_from'])) {
            $where .= ' AND DATE(r.issued_at) >= ?';
            $params[] = $filters['date_from'];
        }
        if (!empty($filters['date_to'])) {
            $where .= ' AND DATE(r.issued_at) <= ?';
            $params[] = $filters['date_to'];
        }
        if (!empty($filters['search'])) {
            $where .= ' AND (r.receipt_number LIKE ? OR m.full_name_ar LIKE ? OR m.membership_number LIKE ?)';
            $s = '%' . $filters['search'] . '%';
            $params[] = $s; $params[] = $s; $params[] = $s;
        }

        $countRow = $db->selectOne("SELECT COUNT(*) as cnt FROM receipts r JOIN members m ON m.id = r.member_id WHERE {$where}", $params);
        $total = (int) ($countRow['cnt'] ?? 0);
        $offset = ($page - 1) * $perPage;

        $rows = $db->select(
            "SELECT r.*, m.full_name_ar as member_name, m.membership_number, e.full_name_ar as issued_by_name
             FROM receipts r
             JOIN members m ON m.id = r.member_id
             LEFT JOIN employees e ON e.id = r.issued_by_employee_id
             WHERE {$where}
             ORDER BY r.id DESC
             LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

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

    public static function incrementPrintCount(int $id): void
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();
        $db->update('receipts', [
            'print_count'     => new \stdClass(), // hack: we'll use raw SQL below
            'last_printed_at' => date('Y-m-d H:i:s'),
            'last_printed_by' => $employee ? (int) $employee->id : null,
        ], '`id` = ?', [$id]);
        // Use raw query for increment
        $db->query("UPDATE receipts SET print_count = print_count + 1 WHERE id = ?", [$id]);
    }
}