<?php

declare(strict_types=1);

namespace App\Controllers;

use Core\Request;

final class CashierController extends BaseController
{
    public function __construct()
    {
        parent::__construct();
    }

    public function index(): void
    {
        $this->requirePermission('cashier.view');

        $orders = $this->db->fetchAll(
            "SELECT o.id, o.order_number, o.total_amount, o.payment_method,
                    o.payment_status, o.collected_via, o.order_type, o.status, o.placed_at,
                    o.rider_id,
                    COALESCE(u.name,  o.guest_name)  AS customer_name,
                    COALESCE(u.phone, o.guest_phone) AS customer_phone,
                    r.name AS rider_name
               FROM orders o
               LEFT JOIN customers c ON c.id = o.customer_id
               LEFT JOIN users u     ON u.id = c.user_id
               LEFT JOIN users r     ON r.id = o.rider_id
              WHERE (o.payment_status IS NULL OR o.payment_status != 'paid')
                AND o.status NOT IN ('cancelled')
              ORDER BY o.placed_at DESC"
        );

        $modes = $this->db->fetchAll(
            "SELECT id, name FROM payment_modes WHERE is_active = 1 ORDER BY sort_order, id"
        );

        // Today's collected orders with their payment splits
        $collected = $this->db->fetchAll(
            "SELECT o.id, o.order_number, o.total_amount, o.order_type, o.status,
                    o.placed_at, o.collected_via,
                    COALESCE(u.name,  o.guest_name)  AS customer_name,
                    r.name AS rider_name
               FROM orders o
               LEFT JOIN customers c ON c.id = o.customer_id
               LEFT JOIN users u     ON u.id = c.user_id
               LEFT JOIN users r     ON r.id = o.rider_id
              WHERE o.payment_status = 'paid'
                AND DATE(o.placed_at) = CURDATE()
              ORDER BY o.placed_at DESC"
        );

        // Fetch splits for collected orders in one query
        $collectedIds = array_column($collected, 'id');
        $splits = [];
        if ($collectedIds) {
            $in   = implode(',', array_fill(0, count($collectedIds), '?'));
            $rows = $this->db->fetchAll(
                "SELECT order_id, mode, amount FROM order_payments WHERE order_id IN ($in) ORDER BY id",
                $collectedIds
            );
            foreach ($rows as $r) {
                $splits[$r['order_id']][] = $r;
            }
        }

        $this->view('cashier/index', [
            'title'        => 'Cashier',
            'orders'       => $orders,
            'collected'    => $collected,
            'splits'       => $splits,
            'paymentModes' => $modes,
        ]);
    }

    public function markPaid(array $params = []): void
    {
        $this->requirePermission('cashier.manage');
        Request::verifyCsrf();

        $id    = (int)($params['id'] ?? 0);
        $order = $this->db->fetchOne("SELECT id, total_amount, payment_status FROM orders WHERE id = ?", [$id]);
        if (!$order) {
            $this->json(['ok' => false, 'message' => 'Order not found'], 404);
            return;
        }

        // Expect splits: modes[] and amounts[] arrays
        $modes   = $_POST['modes']   ?? [];
        $amounts = $_POST['amounts'] ?? [];

        if (empty($modes) || count($modes) !== count($amounts)) {
            $this->json(['ok' => false, 'message' => 'Invalid payment splits.'], 422);
            return;
        }

        $total = 0.0;
        $rows  = [];
        foreach ($modes as $i => $mode) {
            $mode = trim($mode);
            $amt  = round((float)($amounts[$i] ?? 0), 2);
            if ($mode === '' || $amt <= 0) continue;
            $rows[]  = ['order_id' => $id, 'mode' => $mode, 'amount' => $amt];
            $total  += $amt;
        }

        if (empty($rows)) {
            $this->json(['ok' => false, 'message' => 'No valid payment splits.'], 422);
            return;
        }

        // Delete any previous splits for this order, then re-insert
        $this->db->delete('order_payments', ['order_id' => $id]);
        foreach ($rows as $row) {
            $this->db->insert('order_payments', $row);
        }

        // Summarise as comma-separated modes for the legacy collected_via column
        $via = implode(', ', array_unique(array_column($rows, 'mode')));
        $this->db->update('orders', [
            'payment_status' => 'paid',
            'collected_via'  => $via,
        ], ['id' => $id]);

        $this->json(['ok' => true]);
    }
}
