<?php

namespace Easymailing\App\Controller\Admin;

use Easymailing\App\Api\Exception\AuthenticationException;
use Easymailing\App\Controller\BaseController;
use Easymailing\App\Core\Provider\Woocommerce\Hooks\CategoryHooks;
use Easymailing\App\Core\Provider\Woocommerce\Hooks\CustomerHooks;
use Easymailing\App\Core\Provider\Woocommerce\Hooks\OrderHooks;
use Easymailing\App\Core\Provider\Woocommerce\Hooks\ProductHooks;
use Easymailing\App\Core\Provider\Woocommerce\Model\BatchSynchronizationPhase;
use Easymailing\App\Core\Provider\Woocommerce\Model\BatchSynchronizationStatus;
use Easymailing\App\Core\Provider\Woocommerce\Service\BatchEnqueueManager;
use Easymailing\App\Core\Provider\Woocommerce\Service\MetadataHelper;
use Easymailing\App\Utils\DateUtils;


class AjaxController extends BaseController
{
	public function isApiKeyValidAction()
	{
		$client = $this->getApiClient();
		$config = $this->getConfig();

		if ($config and $config->getApiKey()) {
			try {
				$client->checkAuth($config->getApiKey());
				wp_send_json([
					'valid' => true
				]);
				wp_die();
			} catch (AuthenticationException $e) {
				wp_send_json([
					'valid' => false,
					'message' => __('La clave API no es correcta', 'easymailing'),
				]);
				wp_die();
			}
		}

		wp_send_json([
			'valid' => false,
			'message' => __('Tienes que añadir tu clave API a la configuración del plugin', 'easymailing'),
		]);
		wp_die();
	}

	public function getEmbeddedFormsAction()
	{
		$client = $this->getApiClient();
		$audience = $this->getRequest()->query->get('audience');

		$forms = $client->getForms($audience, [
			'type' => 'embedded',
			'active' => true,
		]);

		wp_send_json($forms);
		wp_die();
	}

	public function getPopupFormsAction()
	{
		$client = $this->getApiClient();
		$audience = $this->getRequest()->query->get('audience');
		$forms = $client->getForms($audience, [
			'type' => 'popup',
			'active' => true,
		]);

		wp_send_json($forms);
		wp_die();
	}

	public function getAudiencesAction()
	{
		$client = $this->getApiClient();
		$audiences = $client->getAudiences();
		wp_send_json($audiences);
		wp_die();
	}

	public function getGroupsByAudienceAction()
	{
		$client = $this->getApiClient();
		$repository = $this->getContainer()->get('config_repository');
		$synchronizationConfig = $repository->getSynchronizationConfig();
		$audienceId = $this->getRequest()->query->get('audience_id');
		$groupSelectedId = $synchronizationConfig->getGroup();

		if(!$audienceId){
			return;
		}

		try{
			$audience = $client->getAudienceById($audienceId);
			wp_send_json(["groups" => $audience->groups, 'group_selected' => $groupSelectedId]);
		}catch(\Exception $e){
			wp_send_json(["err" => true]);
		}
		wp_die();
	}

	public function easymailingSynchronization(): void
	{
		if (has_action(BatchEnqueueManager::SYNCHRONIZATION_BACKGROUND_TASK)) {
			update_option(MetadataHelper::getBatchSynchronizationStatus(), BatchSynchronizationStatus::SCHEDULED);
			$batchEnqueueManager = $this->getContainer()->get('batch_enqueue_manager');
			$batchEnqueueManager->enqueue(false);

			wp_send_json(["ok" => true, "synchronization" => __('La sincronización se ha programado con éxito'. 'easymailing')]);
		} else {
			wp_send_json(["ok" => false, "synchronization" => __('No se ha podido programar la sincronización'. 'easymailing')]);
		}
	}

	public function cancelSynchronization(): void
	{
		if (has_action(BatchEnqueueManager::SYNCHRONIZATION_BACKGROUND_TASK)) {
			update_option(MetadataHelper::getBatchSynchronizationStatus(), BatchSynchronizationStatus::CANCELED);
			$batchEnqueueManager = $this->getContainer()->get('batch_enqueue_manager');
			$batchEnqueueManager->cancelScheduledActions();

			wp_send_json(["ok" => true, "synchronization" => __('La sincronización se ha cancelado con éxito'. 'easymailing')]);
		} else {
			wp_send_json(["ok" => false, "synchronization" => __('No se ha podido cancelar la sincronización'. 'easymailing')]);
		}
	}

	public function checkSynchronizationStatus(): void
	{
		$synchronizationStatus = get_option(MetadataHelper::getBatchSynchronizationStatus());
		$lastFinishedAt = get_option(MetadataHelper::getLastBatchSynchronization());

		if (!is_bool($lastFinishedAt) && $lastFinishedAt) {
			$lastFinishedAt = DateUtils::formatDateWithTimezone($lastFinishedAt);
		} else {
			$lastFinishedAt = null;
		}

		$working = $synchronizationStatus === BatchSynchronizationStatus::IN_PROGRESS || $synchronizationStatus === BatchSynchronizationStatus::SCHEDULED;

		$baseText = BatchSynchronizationStatus::getTitle($synchronizationStatus);
		$phaseData = $this->buildPhaseData($working);
		$detail = $this->buildDetailText($phaseData, $working);

		wp_send_json([
			"ok" => true,
			"status" => $synchronizationStatus,
			"lastSynchronization" => $lastFinishedAt,
			"text" => $baseText,
			"detail" => $detail,
			"class" => BatchSynchronizationStatus::getClass($synchronizationStatus),
			"working" => $working,
			"phase" => $phaseData['phase'],
			"totalPhases" => BatchSynchronizationPhase::TOTAL_PHASES,
			"phaseLabel" => $phaseData['label'],
			"progress" => $phaseData['progress'],
		]);

		wp_die();
	}

	private function buildPhaseData(bool $working): array
	{
		$empty = [
			'phase' => null,
			'label' => null,
			'progress' => null,
		];

		if (!$working) {
			return $empty;
		}

		$phase = (int) get_option(MetadataHelper::getBatchSynchronizationPhase());
		if ($phase < BatchSynchronizationPhase::STORES_CATEGORIES_CUSTOMERS || $phase >= BatchSynchronizationPhase::DONE) {
			return $empty;
		}

		// Refrescamos desde el API si el snapshot local es viejo (>3s), para que el
		// usuario vea progreso sin esperar al check task (que corre cada ~1 min).
		$this->maybeRefreshProgressFromApi($phase);

		$rawProgress = get_option(MetadataHelper::getBatchSynchronizationProgress());
		$progress = null;

		if ($rawProgress) {
			$decoded = json_decode($rawProgress, true);
			if (is_array($decoded) && isset($decoded['total'])) {
				$total = (int) $decoded['total'];
				$finished = (int) ($decoded['finished'] ?? 0);
				$errored = (int) ($decoded['errored'] ?? 0);
				$percent = $total > 0 ? min(100, (int) floor($finished * 100 / $total)) : 0;
				$progress = [
					'total' => $total,
					'finished' => $finished,
					'errored' => $errored,
					'percent' => $percent,
				];
			}
		}

		return [
			'phase' => $phase,
			'label' => BatchSynchronizationPhase::getLabel($phase),
			'progress' => $progress,
		];
	}

	private function maybeRefreshProgressFromApi(int $phase): void
	{
		$rawProgress = get_option(MetadataHelper::getBatchSynchronizationProgress());
		$decoded = $rawProgress ? json_decode($rawProgress, true) : null;

		$isSamePhase = is_array($decoded) && (int) ($decoded['phase'] ?? 0) === $phase;
		$updatedAt = $isSamePhase ? (int) ($decoded['updatedAt'] ?? 0) : 0;

		// Throttle: a lo sumo una consulta al API cada 3 segundos.
		if ($isSamePhase && $updatedAt > 0 && (time() - $updatedAt) < 3) {
			return;
		}

		$rawIris = get_option(MetadataHelper::getApiBatchOperationsIris());
		if (!$rawIris) {
			return;
		}

		$iris = json_decode($rawIris);
		if (empty($iris) || !is_array($iris)) {
			return;
		}

		$total = 0;
		$finished = 0;
		$errored = 0;

		try {
			$apiClient = $this->getApiClient();
			foreach ($iris as $iri) {
				$batchOperation = $apiClient->getBatchOperation($iri);
				$total    += (int) $batchOperation->total;
				$finished += (int) $batchOperation->finished;
				$errored  += (int) $batchOperation->errored;
			}
		} catch (\Exception $e) {
			// Si falla la consulta, mantenemos el snapshot previo.
			return;
		}

		update_option(MetadataHelper::getBatchSynchronizationProgress(), json_encode([
			'phase' => $phase,
			'total' => $total,
			'finished' => $finished,
			'errored' => $errored,
			'updatedAt' => time(),
		]));
	}

	private function buildDetailText(array $phaseData, bool $working): string
	{
		if (!$working || $phaseData['phase'] === null) {
			return '';
		}

		$parts = [];
		$parts[] = sprintf(
			/* translators: 1: current phase number, 2: total phase count, 3: phase label */
			__('Fase %1$d de %2$d · %3$s', 'easymailing'),
			$phaseData['phase'],
			BatchSynchronizationPhase::TOTAL_PHASES,
			$phaseData['label']
		);

		$progress = $phaseData['progress'];
		if ($progress && $progress['total'] > 0) {
			$parts[] = sprintf(
				/* translators: 1: percent, 2: finished count, 3: total count */
				__('%1$d%% (%2$d / %3$d)', 'easymailing'),
				$progress['percent'],
				$progress['finished'],
				$progress['total']
			);
		}

		return implode(' — ', $parts);
	}


	private function sendResponse(string $status, ?string $lastSynchronization, string $text, string $class, bool $working)
	{
		wp_send_json([
			"ok" => true,
			"status" => $status,
			"lastSynchronization" => $lastSynchronization ,
			"text" => $text,
			"class" => $class,
			"working" => $working
		]);
		wp_die();
	}

	public function resynchronizeResource(): void
	{
		$id = (int) sanitize_text_field($_REQUEST['id']);
		$type = sanitize_text_field($_REQUEST['type']);

//		/** @var LogManager $logManager */
//		$logManager = $this->getContainer()->get('log_manager');

//		try {
			switch ($type) {
				case 'category':
					/** @var CategoryHooks $categoryHooks */
					$categoryHooks = $this->getContainer()->get('category_hooks');
					$categoryHooks->synchronizeCategoryAdmin($id);
					break;

				case 'product':
					/** @var ProductHooks $productHooks */
					$productHooks = $this->getContainer()->get('product_hooks');
					$productHooks->synchronizeProductAdmin($id);
					break;

				case 'order':
					/** @var OrderHooks $orderHooks */
					$orderHooks = $this->getContainer()->get('order_hooks');
					$orderHooks->synchronizeOrderAdmin($id);
					break;

				case 'customer':
					/** @var CustomerHooks $customerHooks */
					$customerHooks = $this->getContainer()->get('customer_hooks');
					$customerHooks->synchronizeCustomerAdmin($id);
					break;

				default:
					throw new \Exception("Tipo de recurso no válido: $type");
			}

			wp_send_json(["response" => "OK"]);
//		} catch (\Exception $e) {
//			$logManager->createLog(LogType::ERROR, $e->getMessage());
////			wp_send_json(["ERROR" => $e->getMessage(), "response" => "FALSE"]);
//			wp_send_json(["response" => "OK"]);
//		} finally {
//			wp_die();
//		}
	}



}
