<?php
class CardPrintController extends Controller
{
    public function index(Request $request): void
    {
        $this->view('cards/print_batches', [
            'title'       => lang('cards.print_batches'),
            'breadcrumbs' => [
                ['label' => lang('cards.module'), 'url' => '/cards'],
                ['label' => lang('cards.print_batches')],
            ],
        ]);
    }

    public function store(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid CSRF token'], 403);
            return;
        }

        $db = $this->db();

        $pendingRequests = $db->fetchAll(
            "SELECT cr.id AS request_id, cr.resulting_card_id
             FROM card_requests cr
             WHERE cr.status = 'approved' AND cr.resulting_card_id IS NOT NULL
             ORDER BY cr.id"
        );

        if (empty($pendingRequests)) {
            $this->json(['success' => false, 'message' => lang('cards.no_cards_to_print')]);
            return;
        }

        $batchNumber = SequenceGenerator::next('print_batch_number');

        $batchId = $db->insert('card_print_batches', [
            'batch_number' => $batchNumber,
            'batch_date'   => date('Y-m-d'),
            'total_cards'  => count($pendingRequests),
            'status'       => 'pending',
        ]);

        foreach ($pendingRequests as $pr) {
            $db->insert('card_print_batch_items', [
                'batch_id'        => $batchId,
                'card_request_id' => $pr['request_id'],
                'card_id'         => $pr['resulting_card_id'],
                'print_status'    => 'pending',
            ]);

            $db->update('card_requests', ['status' => 'in_production'], 'id = ?', [$pr['request_id']]);
        }

        $this->audit('create', 'card_print_batches', $batchId, "Print batch created: {$batchNumber} with " . count($pendingRequests) . " cards");

        $this->json(['success' => true, 'message' => lang('cards.batch_created'), 'redirect' => '/cards/print-batches']);
    }

    public function process(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid CSRF token'], 403);
            return;
        }

        $batchId = (int)$request->routeParam('id');
        $db = $this->db();

        $batch = $db->fetchOne("SELECT * FROM card_print_batches WHERE id = ? AND status IN ('pending','partial')", [$batchId]);
        if (!$batch) {
            $this->json(['success' => false, 'message' => 'Batch not found or already completed'], 404);
            return;
        }

        $items = $db->fetchAll("SELECT * FROM card_print_batch_items WHERE batch_id = ? AND print_status = 'pending'", [$batchId]);

        $printedCount = 0;
        $failedCount = 0;

        foreach ($items as $item) {
            $db->update('card_print_batch_items', ['print_status' => 'printed'], 'id = ?', [$item['id']]);

            if ($item['card_id']) {
                $db->update('member_cards', [
                    'print_count'     => $db->fetchColumn("SELECT print_count FROM member_cards WHERE id = ?", [$item['card_id']]) + 1,
                    'last_printed_at' => date('Y-m-d H:i:s'),
                ], 'id = ?', [$item['card_id']]);
            }

            if ($item['card_request_id']) {
                $db->update('card_requests', [
                    'status'      => 'ready',
                    'produced_at' => date('Y-m-d H:i:s'),
                ], 'id = ?', [$item['card_request_id']]);
            }

            $printedCount++;
        }

        $totalPrinted = (int)$db->fetchColumn("SELECT COUNT(*) FROM card_print_batch_items WHERE batch_id = ? AND print_status = 'printed'", [$batchId]);
        $totalFailed  = (int)$db->fetchColumn("SELECT COUNT(*) FROM card_print_batch_items WHERE batch_id = ? AND print_status = 'failed'", [$batchId]);

        $status = 'completed';
        if ($totalFailed > 0 && $totalPrinted > 0) $status = 'partial';
        if ($totalPrinted === 0) $status = 'cancelled';

        $db->update('card_print_batches', [
            'printed_cards' => $totalPrinted,
            'failed_cards'  => $totalFailed,
            'status'        => $status,
            'printed_by'    => Auth::id(),
            'printed_at'    => date('Y-m-d H:i:s'),
        ], 'id = ?', [$batchId]);

        $this->audit('update', 'card_print_batches', $batchId, "Print batch processed: {$totalPrinted} printed, {$totalFailed} failed");

        $this->json(['success' => true, 'message' => lang('cards.batch_processed')]);
    }
}