<?php
class WaitingListApiController extends Controller
{
    public function datatable(Request $request): void
    {
        $db = $this->db();
        $draw   = (int) $request->get('draw', 1);
        $start  = (int) $request->get('start', 0);
        $length = (int) $request->get('length', 25);

        $rows = $db->fetchAll(
            "SELECT wl.*, mt.name_en as type_name_en, mt.name_ar as type_name_ar,
                    (SELECT COUNT(*) FROM waiting_list_entries wle WHERE wle.waiting_list_id = wl.id AND wle.status = 'waiting') as waiting_count,
                    (SELECT COUNT(*) FROM waiting_list_entries wle WHERE wle.waiting_list_id = wl.id AND wle.status = 'offered') as offered_count
             FROM waiting_lists wl
             JOIN membership_types mt ON wl.membership_type_id = mt.id
             ORDER BY mt.sort_order
             LIMIT " . (int)$length . " OFFSET " . (int)$start
        );

        $total = (int) $db->fetchColumn("SELECT COUNT(*) FROM waiting_lists");

        $data = [];
        foreach ($rows as $r) {
            $status = $r['is_open'] ? '<span class="badge bg-success">Open</span>' : '<span class="badge bg-danger">Closed</span>';

            $data[] = [
                'id'      => $r['id'],
                'type'    => e(current_lang() === 'ar' ? $r['type_name_ar'] : $r['type_name_en']),
                'max'     => $r['max_entries'] ?? '∞',
                'current' => $r['current_entries'],
                'waiting' => $r['waiting_count'],
                'offered' => $r['offered_count'],
                'status'  => $status,
            ];
        }

        $this->json([
            'draw'            => $draw,
            'recordsTotal'    => $total,
            'recordsFiltered' => $total,
            'data'            => $data,
        ]);
    }

    public function entriesDatatable(Request $request): void
    {
        $db = $this->db();
        $draw   = (int) $request->get('draw', 1);
        $start  = (int) $request->get('start', 0);
        $length = (int) $request->get('length', 25);
        $search = $request->get('search')['value'] ?? '';
        $listId = $request->get('waiting_list_id');

        $where = "1=1";
        $params = [];

        if ($listId) {
            $where .= " AND wle.waiting_list_id = ?";
            $params[] = $listId;
        }
        $statusFilter = $request->get('status');
        if ($statusFilter) {
            $where .= " AND wle.status = ?";
            $params[] = $statusFilter;
        }
        if ($search) {
            $where .= " AND (wle.applicant_name LIKE ? OR wle.applicant_phone LIKE ? OR wle.applicant_national_id LIKE ?)";
            $s = "%{$search}%";
            $params = array_merge($params, [$s, $s, $s]);
        }

        $total = (int) $db->fetchColumn("SELECT COUNT(*) FROM waiting_list_entries wle WHERE {$where}", $params);

        $rows = $db->fetchAll(
            "SELECT wle.*, mt.name_en as type_name_en, mt.name_ar as type_name_ar
             FROM waiting_list_entries wle
             JOIN waiting_lists wl ON wle.waiting_list_id = wl.id
             JOIN membership_types mt ON wl.membership_type_id = mt.id
             WHERE {$where}
             ORDER BY wle.queue_number ASC
             LIMIT " . (int)$length . " OFFSET " . (int)$start,
            $params
        );

        $data = [];
        foreach ($rows as $r) {
            $actions = '<div class="btn-group btn-group-sm">';
            if ($r['status'] === 'waiting') {
                $actions .= '<button class="btn btn-outline-success btn-sm" onclick="offerEntry(' . $r['id'] . ')" title="Offer"><i class="fas fa-paper-plane"></i></button>';
                $actions .= '<button class="btn btn-outline-primary btn-sm" onclick="promoteEntry(' . $r['id'] . ')" title="Promote"><i class="fas fa-arrow-up"></i></button>';
            }
            $actions .= '<button class="btn btn-outline-danger btn-sm" onclick="removeEntry(' . $r['id'] . ')" title="Remove"><i class="fas fa-times"></i></button>';
            $actions .= '</div>';

            $data[] = [
                'queue_number'  => $r['queue_number'],
                'name'          => e($r['applicant_name']),
                'phone'         => e($r['applicant_phone']),
                'national_id'   => e($r['applicant_national_id'] ?? '-'),
                'type'          => e(current_lang() === 'ar' ? $r['type_name_ar'] : $r['type_name_en']),
                'date'          => format_date($r['registration_date']),
                'priority'      => status_badge($r['priority']),
                'status'        => status_badge($r['status']),
                'actions'       => $actions,
            ];
        }

        $this->json([
            'draw'            => $draw,
            'recordsTotal'    => $total,
            'recordsFiltered' => $total,
            'data'            => $data,
        ]);
    }

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

        $db = $this->db();
        $entry = $db->fetchOne("SELECT wle.*, wl.offer_validity_days FROM waiting_list_entries wle JOIN waiting_lists wl ON wle.waiting_list_id = wl.id WHERE wle.id = ?", [$id]);
        if (!$entry) {
            $this->json(['success' => false, 'message' => 'Entry not found'], 404);
            return;
        }

        $expiresAt = date('Y-m-d H:i:s', strtotime('+' . ($entry['offer_validity_days'] ?? 30) . ' days'));

        $db->update('waiting_list_entries', [
            'status'           => 'offered',
            'offered_at'       => date('Y-m-d H:i:s'),
            'offer_expires_at' => $expiresAt,
        ], 'id = ?', [$id]);

        $db->insert('waiting_list_entry_status_history', [
            'entry_id'    => $id,
            'from_status' => $entry['status'],
            'to_status'   => 'offered',
            'changed_by'  => Auth::id(),
            'notes'       => 'Offer sent, expires: ' . $expiresAt,
        ]);

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

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

        $db = $this->db();
        $entry = $db->fetchOne("SELECT * FROM waiting_list_entries WHERE id = ?", [$id]);
        if (!$entry) {
            $this->json(['success' => false, 'message' => 'Entry not found'], 404);
            return;
        }

        $db->update('waiting_list_entries', [
            'status'      => 'promoted',
            'promoted_at' => date('Y-m-d H:i:s'),
        ], 'id = ?', [$id]);

        $db->insert('waiting_list_entry_status_history', [
            'entry_id'    => $id,
            'from_status' => $entry['status'],
            'to_status'   => 'promoted',
            'changed_by'  => Auth::id(),
        ]);

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

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

        $db = $this->db();
        $entry = $db->fetchOne("SELECT * FROM waiting_list_entries WHERE id = ?", [$id]);
        if (!$entry) {
            $this->json(['success' => false, 'message' => 'Entry not found'], 404);
            return;
        }

        $db->update('waiting_list_entries', [
            'status' => 'withdrawn',
        ], 'id = ?', [$id]);

        $db->insert('waiting_list_entry_status_history', [
            'entry_id'    => $id,
            'from_status' => $entry['status'],
            'to_status'   => 'withdrawn',
            'changed_by'  => Auth::id(),
            'notes'       => $request->post('reason', ''),
        ]);

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

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

        $direction = $request->post('direction', 'up');
        $db = $this->db();
        $entry = $db->fetchOne("SELECT * FROM waiting_list_entries WHERE id = ?", [$id]);
        if (!$entry) {
            $this->json(['success' => false, 'message' => 'Entry not found'], 404);
            return;
        }

        $currentQueue = (int) $entry['queue_number'];
        $newQueue = $direction === 'up' ? $currentQueue - 1 : $currentQueue + 1;

        if ($newQueue < 1) {
            $this->json(['success' => false, 'message' => 'Already at top'], 422);
            return;
        }

        $swapEntry = $db->fetchOne(
            "SELECT id FROM waiting_list_entries WHERE waiting_list_id = ? AND queue_number = ? AND status IN ('waiting','offered')",
            [$entry['waiting_list_id'], $newQueue]
        );

        if ($swapEntry) {
            $db->update('waiting_list_entries', ['queue_number' => $currentQueue], 'id = ?', [$swapEntry['id']]);
        }
        $db->update('waiting_list_entries', ['queue_number' => $newQueue], 'id = ?', [$id]);

        $this->json(['success' => true, 'message' => 'Position updated']);
    }
}