<?php

namespace WooPoPCozmosLabsPMS\Functions;

use WcElectronInvoice\Providers\OrderQuery;

defined( 'ABSPATH' ) || die( 'Not allowed.' );

class Utils {
	/**
	 * Extend duplicate-check lookup for Cozmos numeration.
	 *
	 * @param bool   $exists
	 * @param int    $number
	 * @param string $optionKeyName
	 *
	 * @return bool
	 */
	public static function cozmosNextNumberAlreadyAssigned( $exists, $number, $optionKeyName ) {
		if ( $exists || (int) $number < 1 ) {
			return (bool) $exists;
		}

		$lastAssigned = self::cozmosLastAssignedNumberForSeries( 0, $optionKeyName );

		return ( $lastAssigned > 0 && $lastAssigned === (int) $number );
	}

	/**
	 * Contribute Cozmos last assigned candidate for current series.
	 *
	 * @param array  $candidate
	 * @param string $optionKeyName
	 *
	 * @return array
	 */
	public static function cozmosLastAssignedCandidateForSeries( $candidate, $optionKeyName ) {
		$candidate = \WcElectronInvoice\Functions\normalizeLastAssignedCandidate( $candidate );

		if ( 'number_next_invoice' !== $optionKeyName && 'number_next_receipt' !== $optionKeyName ) {
			return $candidate;
		}

		try {
			$provider = OrderQuery::instance()->get_provider( 'cozmoslabspms' );
			if ( ! $provider || ! method_exists( $provider, 'getOrders' ) ) {
				return $candidate;
			}

			$limit = (int) apply_filters(
				'wc_el_inv-next_number_recent_provider_orders_limit',
				200,
				'cozmoslabspms',
				$optionKeyName,
				0
			);
			if ( $limit < 1 ) {
				$limit = 1;
			}

			$orders = $provider->getOrders( [
				'status'  => [ 'completed', 'processing' ],
				'limit'   => $limit,
				'orderby' => 'date',
				'order'   => 'DESC',
			] );
			if ( ! is_array( $orders ) ) {
				return $candidate;
			}

			$seriesContext = \WcElectronInvoice\Functions\getNextNumberSeriesContext( $optionKeyName );
			$cozmosCandidate = [];

			foreach ( $orders as $order ) {
				if ( ! is_object( $order ) || ! method_exists( $order, 'get_meta' ) ) {
					continue;
				}

				$invoiceNumber = (int) $order->get_meta( 'order_number_invoice', true );
				if ( $invoiceNumber < 1 ) {
					continue;
				}

				$choiceType = (string) $order->get_meta( '_billing_choice_type', true );
				$isReceipt  = ( 'receipt' === $choiceType );
				if ( 'number_next_receipt' === $optionKeyName && ! $isReceipt ) {
					continue;
				}
				if ( 'number_next_invoice' === $optionKeyName && $isReceipt ) {
					continue;
				}

				if ( \WcElectronInvoice\Functions\isOrderInNextNumberSeries( $order, $seriesContext ) ) {
					$cozmosCandidate = [
						'number'    => $invoiceNumber,
						'timestamp' => (int) \WcElectronInvoice\Functions\getOrderComparableTimestamp( $order ),
						'provider'  => 'cozmoslabspms',
						'order_id'  => method_exists( $order, 'get_id' ) ? (int) $order->get_id() : 0,
					];
					break;
				}
			}
		} catch ( \Throwable $e ) {
			return $candidate;
		}

		return \WcElectronInvoice\Functions\pickBetterLastAssignedCandidate( $candidate, $cozmosCandidate );
	}

	/**
	 * Legacy int-based callback kept for backward compatibility.
	 *
	 * @param int    $lastAssigned
	 * @param string $optionKeyName
	 * @param array  $currentCandidate
	 *
	 * @return int
	 */
	public static function cozmosLastAssignedNumberForSeries( $lastAssigned, $optionKeyName, $currentCandidate = [] ) {
		$baseCandidate = \WcElectronInvoice\Functions\normalizeLastAssignedCandidate( array_merge(
			[
				'number' => (int) $lastAssigned,
			],
			is_array( $currentCandidate ) ? $currentCandidate : []
		) );
		$bestCandidate = self::cozmosLastAssignedCandidateForSeries( $baseCandidate, $optionKeyName );

		return (int) $bestCandidate['number'];
	}
}
