<?php

declare(strict_types=1);

namespace App\Modules\Sales\Application\Services;

use PDO;

final class PosSuspendedCartService
{
    public function ensureSessionState(): void
    {
        if (!isset($_SESSION['pos_suspended']) || !is_array($_SESSION['pos_suspended'])) {
            $_SESSION['pos_suspended'] = [];
        }
    }

    public function all(): array
    {
        $this->ensureSessionState();
        return array_values($_SESSION['pos_suspended']);
    }

    public function allForDisplay(PDO $pdo, ?PosCartService $cartService = null): array
    {
        $cartService ??= new PosCartService();
        $rows = [];

        foreach ($this->all() as $entry) {
            $cart = is_array($entry['cart'] ?? null) ? $entry['cart'] : [];
            $snapshot = $this->snapshotForCart($pdo, $cartService, $cart);
            $entry['cart_count'] = $snapshot['cart_count'];
            $entry['cart_total'] = $snapshot['cart_total'];
            $entry['items_count'] = count($cart);
            $rows[] = $entry;
        }

        usort($rows, static function (array $a, array $b): int {
            return strcmp((string)($b['created_at'] ?? ''), (string)($a['created_at'] ?? ''));
        });

        return $rows;
    }

    public function save(array $entry): void
    {
        $this->ensureSessionState();
        $_SESSION['pos_suspended'][$entry['id']] = $entry;
    }

    public function get(string $id): ?array
    {
        $this->ensureSessionState();
        $entry = $_SESSION['pos_suspended'][$id] ?? null;
        return is_array($entry) ? $entry : null;
    }

    public function delete(string $id): void
    {
        $this->ensureSessionState();
        unset($_SESSION['pos_suspended'][$id]);
    }

    public function suspendCurrentCart(PosCartService $cartService, array $form): string
    {
        $entryId = 'S' . date('YmdHis') . random_int(100, 999);
        $this->save([
            'id' => $entryId,
            'created_at' => date('Y-m-d H:i:s'),
            'label' => trim((string)($form['customer_label'] ?? '')),
            'cart' => $cartService->all(),
            'form' => $form,
        ]);
        $cartService->clear();
        return $entryId;
    }

    public function resumeIntoCart(string $id, PosCartService $cartService): ?array
    {
        $entry = $this->get($id);
        if ($entry === null) {
            return null;
        }

        $_SESSION['cart'] = is_array($entry['cart'] ?? null) ? $entry['cart'] : [];
        $this->delete($id);

        return is_array($entry['form'] ?? null) ? $entry['form'] : [];
    }

    private function snapshotForCart(PDO $pdo, PosCartService $cartService, array $cart): array
    {
        $old = $_SESSION['cart'] ?? null;
        $_SESSION['cart'] = $cart;
        try {
            return $cartService->snapshot($pdo);
        } finally {
            if ($old === null) {
                unset($_SESSION['cart']);
            } else {
                $_SESSION['cart'] = $old;
            }
        }
    }
}
