<?php
/**
 * BookiFlex Core
 *
 * @package    BookiFlex
 * @subpackage Core
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */

declare(strict_types=1);

namespace BookiFlex\Core\ORM\Typecast;

use BookiFlex\Core\Model\DateUnit\Pricing\DateUnitPrice;
use Cycle\ORM\Parser\CastableInterface;
use Cycle\ORM\Parser\UncastableInterface;

defined( 'ABSPATH' ) || exit;

class DateUnitTypecast implements CastableInterface, UncastableInterface
{
    public function setRules(array $rules): array
    {
        // Can set rules here if needed
        return $rules;
    }

    public function cast(array $data): array
    {
        if (empty($data['price'])) {
            return $data;
        }

        if (is_string($data['price'])) {
            $price = json_decode($data['price'], true);

            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new \RuntimeException('Invalid JSON in DateUnitPrice: ' . json_last_error_msg());
            }
        } else {
            // is array?
            $price = $data['price'];
        }

        $data['price'] = DateUnitPrice::fromArray($price);

        return $data;
    }

    public function uncast(array $data): array
    {
        if (!isset($data['price'])) {
            return $data;
        }

        if (!$data['price'] instanceof DateUnitPrice) {
            throw new \InvalidArgumentException('Expected DateUnitPrice, got ' . get_class($data['price']));
        }

        // Convert to JSON
        $json = json_encode($data['price']->toArray());

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new \RuntimeException('Failed to serialize DateUnitPrice: ' . json_last_error_msg());
        }
        $data['price'] = $json;

        return $data;
    }
}
