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


declare(strict_types=1);
namespace BookiFlex\Extensions\Cart\Repository;

use BookiFlex\Extensions\Cart\Model\Cart;
use Cycle\ORM\Select;
use Cycle\ORM\Select\QueryBuilder;
use Cycle\ORM\Select\Repository;
use DateTimeImmutable;

defined( 'ABSPATH' ) || exit;

class CartRepository extends Repository
{
    /**
     * Find cart by session ID
     */
    public function findBySessionId(string $sessionId): ?Cart
    {
        return $this->select()
            ->where('session_id', $sessionId)
            ->where('status', 'in', ['pending', 'checkout'])
            ->load('items')
            ->load('customer')
            ->fetchOne();
    }

    /**
     * Find expired carts (pending/checkout older than 3 days).
     *
     * Uses updated_at when available, falls back to created_at when null.
     */
    public function findExpired(): array
    {
        $cutoff = (new DateTimeImmutable())->modify('-3 days')->format('Y-m-d H:i:s');

        return $this->select()
            ->where(function (QueryBuilder $q) use ($cutoff) {
                $q->where(function (QueryBuilder $inner) use ($cutoff) {
                    $inner->where('updated_at', '!=', null)
                          ->where('updated_at', '<', $cutoff);
                })->orWhere(function (QueryBuilder $inner) use ($cutoff) {
                    $inner->where('updated_at', null)
                          ->where('created_at', '<', $cutoff);
                });
            })
            ->fetchAll();
    }

    /**
     * Find abandoned carts for recovery
     */
    public function findAbandonedForRecovery(int $minAge = 3600, int $maxAge = 86400): array
    {
        $minTime = (new DateTimeImmutable())->modify("-{$maxAge} seconds");
        $maxTime = (new DateTimeImmutable())->modify("-{$minAge} seconds");

        return $this->select()
            ->where('status', 'pending')
            ->where('updated_at', 'between', [
                $minTime->format('Y-m-d H:i:s'),
                $maxTime->format('Y-m-d H:i:s')
            ])
            ->load('items')
            ->load('customer')
            ->fetchAll();
    }

    /**
     * Clean up old completed/abandoned carts
     */
//    public function cleanupOldCarts(int $daysToKeep = 30): int
//    {
//        $cutoffDate = (new DateTimeImmutable())->modify("-{$daysToKeep} days");
//
//        return $this->select()
//            ->delete('carts')
//            ->where('status', 'in', ['completed', 'abandoned'])
//            ->where('updated_at', '<', $cutoffDate->format('Y-m-d H:i:s'))
//            ->run();
//    }

    /**
     * Find carts by customer email
     */
    public function findByCustomerEmail(string $email): array
    {
        return $this->select()
            ->with('customer')
            ->where('customer.email', $email)
            ->load('items')
            ->orderBy('created_at', 'DESC')
            ->fetchAll();
    }

    /**
     * Get active carts count
     */
    public function getActiveCartsCount(): int
    {
        return $this->select()
            ->where('status', 'in', ['pending', 'checkout'])
            ->count();
    }
}
