<?php

/**
 * Vvveb
 *
 * Copyright (C) 2022  Ziadin Givan
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

namespace Vvveb\Controller\User;

use function Vvveb\__;
use function Vvveb\model;
use Vvveb\System\User\User;

/**
 * Customer subscription detail controller — view, cancel, pause, resume a single subscription.
 */
#[\AllowDynamicProperties]
class Subscription extends Base {
	/** Subscription status IDs matching the seed data. */
	const STATUS_PENDING   = 1;
	const STATUS_ACTIVE    = 2;
	const STATUS_FAILED    = 3;
	const STATUS_CANCELLED = 4;
	const STATUS_DENIED    = 5;
	const STATUS_EXPIRED   = 6;

	/**
	 * Get the subscription ID from the request.
	 *
	 * @return int|string|false
	 */
	private function getSubscriptionId(): int|string|false {
		return $this->request->get['subscription_id'] ?? false;
	}

	/**
	 * Verify that the subscription belongs to the current user.
	 *
	 * @param int|string $subscriptionId
	 *
	 * @return array|false The subscription data or false if not found / not owned.
	 */
	private function getOwnedSubscription(int|string $subscriptionId): array|false {
		$user    = User::current();
		$userId  = $user['user_id'] ?? 0;

		$model   = model('subscription');
		$result  = $model->get([
			'subscription_id' => $subscriptionId,
			'language_id'      => $this->global['language_id'] ?? 1,
		] + $this->global);

		if ($result && (int)($result['user_id'] ?? 0) === (int)$userId) {
			return $result;
		}

		return false;
	}

	/**
	 * Change subscription status and record a log entry.
	 *
	 * @param int    $statusId
	 * @param string $note
	 *
	 * @return void
	 */
	protected function changeStatus(int $statusId, string $note): void {
		$subscriptionId = $this->getSubscriptionId();

		if (! $subscriptionId) {
			$this->view->errors[] = __('Subscription ID is required!');

			return;
		}

		$subscription = $this->getOwnedSubscription($subscriptionId);

		if (! $subscription) {
			$this->view->errors[] = __('Subscription not found!');

			return;
		}

		$model   = model('subscription');
		$result  = $model->edit([
			'subscription' => [
				'subscription_status_id' => $statusId,
				'updated_at'             => date('Y-m-d H:i:s'),
			],
			'subscription_id' => $subscriptionId,
		] + $this->global);

		if ($result) {
			$logModel = model('subscription_log');
			$logModel->add([
				'subscription_log' => [
					'subscription_id'         => $subscriptionId,
					'subscription_status_id'  => $statusId,
					'notify'                  => 1,
					'note'                    => $note,
					'created_at'              => date('Y-m-d H:i:s'),
				],
			] + $this->global);

			$this->view->success[] = __('Subscription updated!');
		} else {
			$this->view->errors[] = __('Error updating subscription!');
		}
	}

	/**
	 * Display subscription detail page.
	 *
	 * @return void
	 */
	public function index(): void {
		$subscriptionId = $this->getSubscriptionId();

		if ($subscriptionId) {
			$subscription = $this->getOwnedSubscription($subscriptionId);

			if ($subscription) {
				$this->view->subscription = $subscription;

				//load subscription logs
				$logModel = model('subscription_log');
				$logs     = $logModel->getAll([
					'subscription_id' => $subscriptionId,
					'language_id'     => $this->global['language_id'] ?? 1,
				] + $this->global);

				$this->view->subscription_logs = $logs['subscription_log'] ?? [];

				return;
			}
		}

		$this->view->errors[] = __('Subscription not found!');
	}

	/**
	 * Cancel the subscription (customer-initiated).
	 *
	 * @return void
	 */
	public function cancel(): void {
		$note = $this->request->post['note'] ?? __('Cancelled by customer');
		$this->changeStatus(self::STATUS_CANCELLED, $note);
		$this->index();
	}

	/**
	 * Pause the subscription (customer-initiated).
	 *
	 * @return void
	 */
	public function pause(): void {
		$note = $this->request->post['note'] ?? __('Paused by customer');
		$this->changeStatus(self::STATUS_PENDING, $note);
		$this->index();
	}

	/**
	 * Resume the subscription (customer-initiated).
	 *
	 * @return void
	 */
	public function resume(): void {
		$note = $this->request->post['note'] ?? __('Resumed by customer');
		$this->changeStatus(self::STATUS_ACTIVE, $note);
		$this->index();
	}
}
