<?php

/**
 * Subscription Settings Controller V1
 *
 * @package Licenzo\Http\Controller\Api\V1
 */

namespace Licenzo\Http\Controller\Api\V1;

use Licenzo\Framework\Http\Request;
use Licenzo\Helper\Settings;
use Licenzo\Http\Traits\HandlesErrors;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class SubscriptionSettingsController
{
    use HandlesErrors;

    /**
     * Get subscription settings.
     *
     * @return array
     */
    public function get()
    {
        try {
            return $this->successResponse(
                Settings::getSubscriptionSettings(),
                'Subscription settings retrieved successfully'
            );
        } catch (\Exception $e) {
            return $this->handleError($e, 'Failed to retrieve subscription settings');
        }
    }

    /**
     * Update subscription settings.
     *
     * @param Request $request
     * @return array
     */
    public function update(Request $request)
    {
        $data = $request->getSafe([
            'renewal_process' => 'sanitize_text_field',
            'manual_renew_cart_notice' => 'sanitize_textarea_field',
            'stripe_auto_renew' => [$this, 'toYesNo'],
            'auto_renewal_toggle' => [$this, 'toYesNo'],
            'active_role' => 'sanitize_text_field',
            'inactive_role' => 'sanitize_text_field',
            'allow_guest_checkout' => [$this, 'toYesNo'],
            'enforce_login' => [$this, 'toYesNo'],
            'enable_subscriptions' => [$this, 'toYesNo'],
            'default_billing_interval' => 'sanitize_text_field',
            'default_trial_days' => 'intval',
            'grace_period_days' => 'intval',
            'enable_auto_renewal' => [$this, 'toYesNo'],
            'renewal_reminder_days' => 'intval',
            'allow_customer_cancellation' => [$this, 'toYesNo'],
            'allow_pause' => [$this, 'toYesNo'],
            'max_pause_duration' => 'intval',
            'prorate_on_upgrade' => [$this, 'toYesNo'],
            'prorate_on_downgrade' => [$this, 'toYesNo'],
            'failed_payment_retries' => 'intval',
            'retry_interval_days' => 'intval',
            'stripe_webhook_secret' => 'sanitize_text_field',
        ]);

        if (array_key_exists('stripe_webhook_secret', $data)) {
            $secret = (string) ($data['stripe_webhook_secret'] ?? '');
            Settings::update('webhook_settings.stripe_secret', $secret);
            unset($data['stripe_webhook_secret']);
        }

        if (array_key_exists('renewal_process', $data)) {
            $data['renewal_process'] = $this->sanitizeRenewalProcess((string) ($data['renewal_process'] ?? ''));
        }

        if (array_key_exists('default_billing_interval', $data)) {
            $data['default_billing_interval'] = $this->sanitizeBillingInterval((string) ($data['default_billing_interval'] ?? ''));
        }

        if (array_key_exists('default_trial_days', $data)) {
            $data['default_trial_days'] = $this->clampInt((int) ($data['default_trial_days'] ?? 0), 0, 365);
        }

        if (array_key_exists('grace_period_days', $data)) {
            $data['grace_period_days'] = $this->clampInt((int) ($data['grace_period_days'] ?? 7), 0, 90);
        }

        if (array_key_exists('renewal_reminder_days', $data)) {
            $data['renewal_reminder_days'] = $this->clampInt((int) ($data['renewal_reminder_days'] ?? 7), 0, 30);
        }

        if (array_key_exists('max_pause_duration', $data)) {
            $data['max_pause_duration'] = $this->clampInt((int) ($data['max_pause_duration'] ?? 90), 0, 365);
        }

        if (array_key_exists('failed_payment_retries', $data)) {
            $data['failed_payment_retries'] = $this->clampInt((int) ($data['failed_payment_retries'] ?? 3), 0, 10);
        }

        if (array_key_exists('retry_interval_days', $data)) {
            $data['retry_interval_days'] = $this->clampInt((int) ($data['retry_interval_days'] ?? 3), 1, 30);
        }

        try {
            $settings = Settings::updateSubscriptionSettings($data);

            return $this->successResponse(
                $settings,
                'Subscription settings updated successfully'
            );
        } catch (\Exception $e) {
            return $this->handleError($e, 'Failed to update subscription settings');
        }
    }

    /**
     * Normalize boolean-like values into yes/no strings.
     *
     * @param mixed $value
     * @return string
     */
    private function toYesNo($value): string
    {
        if (is_bool($value)) {
            return $value ? 'yes' : 'no';
        }

        if (is_numeric($value)) {
            return ((int) $value === 1) ? 'yes' : 'no';
        }

        if (is_string($value)) {
            $normalized = strtolower(trim($value));

            if (in_array($normalized, ['1', 'true', 'yes', 'on'], true)) {
                return 'yes';
            }
        }

        return 'no';
    }

    /**
     * Enforce supported billing intervals.
     *
     * @param string $interval
     * @return string
     */
    private function sanitizeBillingInterval(string $interval): string
    {
        $allowed = ['day', 'week', 'month', 'year'];

        return in_array($interval, $allowed, true) ? $interval : 'month';
    }

    /**
     * Enforce supported renewal process values.
     *
     * @param string $process
     * @return string
     */
    private function sanitizeRenewalProcess(string $process): string
    {
        $allowed = ['auto', 'manual'];

        return in_array($process, $allowed, true) ? $process : 'auto';
    }

    /**
     * Clamp integer to a safe numeric range.
     *
     * @param int $value
     * @param int $min
     * @param int $max
     * @return int
     */
    private function clampInt(int $value, int $min, int $max): int
    {
        return max($min, min($max, $value));
    }
}
