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

    public function create(Request $request): void
    {
        $db = $this->db();
        $cardTypes = $db->fetchAll("SELECT id, type_code, name_en, name_ar, fee, replacement_fee, applicable_to FROM card_types WHERE is_active = 1 ORDER BY name_en");

        $this->view('cards/request_create', [
            'title'       => lang('cards.new_request'),
            'breadcrumbs' => [
                ['label' => lang('cards.module'), 'url' => '/cards'],
                ['label' => lang('cards.card_requests'), 'url' => '/cards/requests'],
                ['label' => lang('cards.new_request')],
            ],
            'cardTypes' => $cardTypes,
        ]);
    }

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

        $validator = new Validator($request->all(), [
            'member_id'    => 'required|integer|exists:members,id',
            'card_type_id' => 'required|integer|exists:card_types,id',
            'request_type' => 'required|in:new,replacement,renewal',
            'reason'       => 'nullable|string|max:500',
            'old_card_id'  => 'nullable|integer',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $db = $this->db();

        $cardType = $db->fetchOne("SELECT * FROM card_types WHERE id = ?", [$data['card_type_id']]);
        $feeAmount = ($data['request_type'] === 'replacement') ? (float)$cardType['replacement_fee'] : (float)$cardType['fee'];

        $requestNumber = SequenceGenerator::next('card_request_number');

        $id = $db->insert('card_requests', [
            'request_number' => $requestNumber,
            'member_id'      => $data['member_id'],
            'card_type_id'   => $data['card_type_id'],
            'request_type'   => $data['request_type'],
            'reason'         => $data['reason'] ?? null,
            'old_card_id'    => $data['old_card_id'] ?? null,
            'status'         => 'pending',
            'fee_amount'     => $feeAmount,
            'fee_paid'       => 0,
            'created_by'     => Auth::id(),
        ]);

        if ($data['request_type'] === 'replacement' && !empty($data['old_card_id'])) {
            $db->update('member_cards', [
                'status'            => 'replaced',
                'status_reason'     => 'Replacement requested: ' . $requestNumber,
                'status_changed_at' => date('Y-m-d H:i:s'),
            ], 'id = ?', [$data['old_card_id']]);
        }

        $this->audit('create', 'card_requests', $id, "Card request created: {$requestNumber}");

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

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

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

        $cardReq = $db->fetchOne("SELECT * FROM card_requests WHERE id = ? AND status = 'pending'", [$id]);
        if (!$cardReq) {
            $this->json(['success' => false, 'message' => 'Request not found or not pending'], 404);
            return;
        }

        $cardNumber = SequenceGenerator::next('card_number');
        $cardType = $db->fetchOne("SELECT * FROM card_types WHERE id = ?", [$cardReq['card_type_id']]);
        $expiryDate = $cardType['validity_months'] ? date('Y-m-d', strtotime("+{$cardType['validity_months']} months")) : null;

        $member = $db->fetchOne("SELECT photo_path FROM members WHERE id = ?", [$cardReq['member_id']]);

        $cardId = $db->insert('member_cards', [
            'card_number'      => $cardNumber,
            'card_type_id'     => $cardReq['card_type_id'],
            'member_id'        => $cardReq['member_id'],
            'dependent_id'     => $cardReq['dependent_id'],
            'barcode'          => $cardNumber,
            'qr_code_data'     => json_encode(['card' => $cardNumber, 'member' => $cardReq['member_id']]),
            'issue_date'       => date('Y-m-d'),
            'expiry_date'      => $expiryDate,
            'status'           => 'active',
            'photo_path'       => $member['photo_path'] ?? null,
            'replaces_card_id' => $cardReq['old_card_id'],
            'created_by'       => Auth::id(),
        ]);

        if ($cardReq['old_card_id']) {
            $db->update('member_cards', ['replaced_by_card_id' => $cardId], 'id = ?', [$cardReq['old_card_id']]);
        }

        $db->update('card_requests', [
            'status'            => 'approved',
            'approved_by'       => Auth::id(),
            'approved_at'       => date('Y-m-d H:i:s'),
            'resulting_card_id' => $cardId,
        ], 'id = ?', [$id]);

        $this->audit('update', 'card_requests', $id, "Card request approved, card {$cardNumber} created");

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

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

        $id = (int)$request->routeParam('id');
        $reason = trim($request->post('reason', ''));
        $db = $this->db();

        $cardReq = $db->fetchOne("SELECT * FROM card_requests WHERE id = ? AND status = 'pending'", [$id]);
        if (!$cardReq) {
            $this->json(['success' => false, 'message' => 'Request not found or not pending'], 404);
            return;
        }

        $db->update('card_requests', [
            'status' => 'rejected',
            'notes'  => $reason,
        ], 'id = ?', [$id]);

        $this->audit('update', 'card_requests', $id, "Card request rejected: {$reason}");

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

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

        $id = (int)$request->routeParam('id');
        $deliveredTo = trim($request->post('delivered_to', ''));
        $db = $this->db();

        $cardReq = $db->fetchOne("SELECT * FROM card_requests WHERE id = ? AND status IN ('approved','in_production','ready')", [$id]);
        if (!$cardReq) {
            $this->json(['success' => false, 'message' => 'Request not found or not ready for delivery'], 404);
            return;
        }

        $db->update('card_requests', [
            'status'       => 'delivered',
            'delivered_at' => date('Y-m-d H:i:s'),
            'delivered_to' => $deliveredTo ?: null,
        ], 'id = ?', [$id]);

        $this->audit('update', 'card_requests', $id, "Card delivered to: {$deliveredTo}");

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