<?php

/**
 * Subscriptions API Controller
 *
 * REST API endpoints for subscription management.
 *
 * @package WooNooW\Api
 */

namespace WooNooW\Api;

if (!defined('ABSPATH')) exit;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use WooNooW\Core\ModuleRegistry;
use WooNooW\Modules\Subscription\SubscriptionManager;

class SubscriptionsController
{

    /**
     * Register REST routes
     */
    public static function register_routes()
    {
        // Check if module is enabled
        if (!ModuleRegistry::is_enabled('subscription')) {
            return;
        }

        // Admin routes
        register_rest_route('woonoow/v1', '/subscriptions', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_subscriptions'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);

        register_rest_route('woonoow/v1', '/subscriptions/(?P<id>\d+)', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_subscription'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);

        register_rest_route('woonoow/v1', '/subscriptions/(?P<id>\d+)', [
            'methods' => 'PUT',
            'callback' => [__CLASS__, 'update_subscription'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);

        register_rest_route('woonoow/v1', '/subscriptions/(?P<id>\d+)/cancel', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'cancel_subscription'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);

        register_rest_route('woonoow/v1', '/subscriptions/(?P<id>\d+)/renew', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'renew_subscription'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);

        register_rest_route('woonoow/v1', '/subscriptions/(?P<id>\d+)/pause', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'pause_subscription'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);

        register_rest_route('woonoow/v1', '/subscriptions/(?P<id>\d+)/resume', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'resume_subscription'],
            'permission_callback' => function () {
                return current_user_can('manage_woocommerce');
            },
        ]);

        // Customer routes
        register_rest_route('woonoow/v1', '/account/subscriptions', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_customer_subscriptions'],
            'permission_callback' => function () {
                return is_user_logged_in();
            },
        ]);

        register_rest_route('woonoow/v1', '/account/subscriptions/(?P<id>\d+)', [
            'methods' => 'GET',
            'callback' => [__CLASS__, 'get_customer_subscription'],
            'permission_callback' => function () {
                return is_user_logged_in();
            },
        ]);

        register_rest_route('woonoow/v1', '/account/subscriptions/(?P<id>\d+)/cancel', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'customer_cancel'],
            'permission_callback' => function () {
                return is_user_logged_in();
            },
        ]);

        register_rest_route('woonoow/v1', '/account/subscriptions/(?P<id>\d+)/pause', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'customer_pause'],
            'permission_callback' => function () {
                return is_user_logged_in();
            },
        ]);

        register_rest_route('woonoow/v1', '/account/subscriptions/(?P<id>\d+)/resume', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'customer_resume'],
            'permission_callback' => function () {
                return is_user_logged_in();
            },
        ]);

        register_rest_route('woonoow/v1', '/account/subscriptions/(?P<id>\d+)/renew', [
            'methods' => 'POST',
            'callback' => [__CLASS__, 'customer_renew'],
            'permission_callback' => function () {
                return is_user_logged_in();
            },
        ]);
    }

    /**
     * Get all subscriptions (admin)
     */
    public static function get_subscriptions(WP_REST_Request $request)
    {
        $args = [
            'status' => $request->get_param('status'),
            'product_id' => $request->get_param('product_id'),
            'user_id' => $request->get_param('user_id'),
            'limit' => $request->get_param('per_page') ?: 20,
            'offset' => (($request->get_param('page') ?: 1) - 1) * ($request->get_param('per_page') ?: 20),
        ];

        $subscriptions = SubscriptionManager::get_all($args);
        $total = SubscriptionManager::count(['status' => $args['status']]);

        // Enrich with product and user info
        $enriched = [];
        foreach ($subscriptions as $subscription) {
            $enriched[] = self::enrich_subscription($subscription);
        }

        return new WP_REST_Response([
            'subscriptions' => $enriched,
            'total' => $total,
            'page' => $request->get_param('page') ?: 1,
            'per_page' => $args['limit'],
        ]);
    }

    /**
     * Get single subscription (admin)
     */
    public static function get_subscription(WP_REST_Request $request)
    {
        $subscription = SubscriptionManager::get($request->get_param('id'));

        if (!$subscription) {
            return new WP_Error('not_found', __('Subscription not found', 'woonoow'), ['status' => 404]);
        }

        $enriched = self::enrich_subscription($subscription);
        $enriched['orders'] = SubscriptionManager::get_orders($subscription->id);

        return new WP_REST_Response($enriched);
    }

    /**
     * Update subscription (admin)
     */
    public static function update_subscription(WP_REST_Request $request)
    {
        global $wpdb;

        $subscription = SubscriptionManager::get($request->get_param('id'));

        if (!$subscription) {
            return new WP_Error('not_found', __('Subscription not found', 'woonoow'), ['status' => 404]);
        }

        $data = $request->get_json_params();
        $allowed_fields = ['status', 'next_payment_date', 'end_date', 'billing_period', 'billing_interval'];

        $update_data = [];
        $format = [];

        foreach ($allowed_fields as $field) {
            if (isset($data[$field])) {
                $update_data[$field] = $data[$field];
                $format[] = is_numeric($data[$field]) ? '%d' : '%s';
            }
        }

        if (empty($update_data)) {
            return new WP_Error('no_data', __('No valid fields to update', 'woonoow'), ['status' => 400]);
        }

        $table = $wpdb->prefix . 'woonoow_subscriptions';
        $updated = $wpdb->update($table, $update_data, ['id' => $subscription->id], $format, ['%d']);

        if ($updated === false) {
            return new WP_Error('update_failed', __('Failed to update subscription', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response(['success' => true]);
    }

    /**
     * Cancel subscription (admin)
     */
    public static function cancel_subscription(WP_REST_Request $request)
    {
        $data = $request->get_json_params();
        $reason = $data['reason'] ?? 'Cancelled by admin';

        $result = SubscriptionManager::cancel($request->get_param('id'), $reason);

        if (!$result) {
            return new WP_Error('cancel_failed', __('Failed to cancel subscription', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response(['success' => true]);
    }

    /**
     * Renew subscription (admin - force immediate renewal)
     */
    public static function renew_subscription(WP_REST_Request $request)
    {
        $result = SubscriptionManager::renew($request->get_param('id'));

        if (!$result) {
            return new WP_Error('renew_failed', __('Failed to process renewal', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response(['success' => true, 'order_id' => $result['order_id']]);
    }

    /**
     * Pause subscription (admin)
     */
    public static function pause_subscription(WP_REST_Request $request)
    {
        $result = SubscriptionManager::pause($request->get_param('id'));

        if (!$result) {
            return new WP_Error('pause_failed', __('Failed to pause subscription', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response(['success' => true]);
    }

    /**
     * Resume subscription (admin)
     */
    public static function resume_subscription(WP_REST_Request $request)
    {
        $result = SubscriptionManager::resume($request->get_param('id'));

        if (!$result) {
            return new WP_Error('resume_failed', __('Failed to resume subscription', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response(['success' => true]);
    }

    /**
     * Get customer's subscriptions
     */
    public static function get_customer_subscriptions(WP_REST_Request $request)
    {
        $user_id = get_current_user_id();
        $subscriptions = SubscriptionManager::get_by_user($user_id, [
            'status' => $request->get_param('status'),
            'limit' => $request->get_param('per_page') ?: 20,
            'offset' => (($request->get_param('page') ?: 1) - 1) * ($request->get_param('per_page') ?: 20),
        ]);

        // Enrich each subscription
        $enriched = [];
        foreach ($subscriptions as $subscription) {
            $enriched[] = self::enrich_subscription($subscription);
        }

        return new WP_REST_Response($enriched);
    }

    /**
     * Get customer's subscription detail
     */
    public static function get_customer_subscription(WP_REST_Request $request)
    {
        $user_id = get_current_user_id();
        $subscription = SubscriptionManager::get($request->get_param('id'));

        if (!$subscription || $subscription->user_id != $user_id) {
            return new WP_Error('not_found', __('Subscription not found', 'woonoow'), ['status' => 404]);
        }

        $enriched = self::enrich_subscription($subscription);
        $enriched['orders'] = SubscriptionManager::get_orders($subscription->id);

        return new WP_REST_Response($enriched);
    }

    /**
     * Customer cancel their own subscription
     */
    public static function customer_cancel(WP_REST_Request $request)
    {
        // Check if customer cancellation is allowed
        $settings = ModuleRegistry::get_settings('subscription');
        if (empty($settings['allow_customer_cancel'])) {
            return new WP_Error('not_allowed', __('Customer cancellation is not allowed', 'woonoow'), ['status' => 403]);
        }

        $user_id = get_current_user_id();
        $subscription = SubscriptionManager::get($request->get_param('id'));

        if (!$subscription || $subscription->user_id != $user_id) {
            return new WP_Error('not_found', __('Subscription not found', 'woonoow'), ['status' => 404]);
        }

        $data = $request->get_json_params();
        $reason = $data['reason'] ?? 'Cancelled by customer';

        $result = SubscriptionManager::cancel($subscription->id, $reason);

        if (!$result) {
            return new WP_Error('cancel_failed', __('Failed to cancel subscription', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response(['success' => true]);
    }

    /**
     * Customer pause their own subscription
     */
    public static function customer_pause(WP_REST_Request $request)
    {
        // Check if customer pause is allowed
        $settings = ModuleRegistry::get_settings('subscription');
        if (empty($settings['allow_customer_pause'])) {
            return new WP_Error('not_allowed', __('Customer pause is not allowed', 'woonoow'), ['status' => 403]);
        }

        $user_id = get_current_user_id();
        $subscription = SubscriptionManager::get($request->get_param('id'));

        if (!$subscription || $subscription->user_id != $user_id) {
            return new WP_Error('not_found', __('Subscription not found', 'woonoow'), ['status' => 404]);
        }

        $result = SubscriptionManager::pause($subscription->id);

        if (!$result) {
            return new WP_Error('pause_failed', __('Failed to pause subscription. Maximum pauses may have been reached.', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response(['success' => true]);
    }

    /**
     * Customer resume their own subscription
     */
    public static function customer_resume(WP_REST_Request $request)
    {
        $user_id = get_current_user_id();
        $subscription = SubscriptionManager::get($request->get_param('id'));

        if (!$subscription || $subscription->user_id != $user_id) {
            return new WP_Error('not_found', __('Subscription not found', 'woonoow'), ['status' => 404]);
        }

        $result = SubscriptionManager::resume($subscription->id);

        if (!$result) {
            return new WP_Error('resume_failed', __('Failed to resume subscription', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response(['success' => true]);
    }

    /**
     * Customer renew their own subscription (Early Renewal)
     */
    public static function customer_renew(WP_REST_Request $request)
    {
        $user_id = get_current_user_id();
        $subscription = SubscriptionManager::get($request->get_param('id'));

        if (!$subscription || $subscription->user_id != $user_id) {
            return new WP_Error('not_found', __('Subscription not found', 'woonoow'), ['status' => 404]);
        }

        // Check if subscription is active (for early renewal) or on-hold with no pending payment
        if ($subscription->status !== 'active' && $subscription->status !== 'on-hold') {
            return new WP_Error('not_allowed', __('Only active subscriptions can be renewed early', 'woonoow'), ['status' => 403]);
        }

        // Trigger renewal
        $result = SubscriptionManager::renew($subscription->id);

        // SubscriptionManager::renew returns array (success) or false (failed)
        if (!$result) {
            return new WP_Error('renew_failed', __('Failed to create renewal order', 'woonoow'), ['status' => 500]);
        }

        return new WP_REST_Response([
            'success' => true,
            'order_id' => $result['order_id'],
            'status' => $result['status']
        ]);
    }

    /**
     * Enrich subscription with product and user info
     */
    private static function enrich_subscription($subscription)
    {
        $enriched = (array) $subscription;

        // Add product info
        $product_id = $subscription->variation_id ?: $subscription->product_id;
        $product = wc_get_product($product_id);
        $enriched['product_name'] = $product ? $product->get_name() : __('Unknown Product', 'woonoow');
        $enriched['product_image'] = $product ? wp_get_attachment_url($product->get_image_id()) : '';

        // Add user info
        $user = get_userdata($subscription->user_id);
        $enriched['user_email'] = $user ? $user->user_email : '';
        $enriched['user_name'] = $user ? $user->display_name : __('Unknown User', 'woonoow');

        // Add computed fields
        $enriched['is_active'] = $subscription->status === 'active';
        $enriched['can_pause'] = $subscription->status === 'active';
        $enriched['can_resume'] = $subscription->status === 'on-hold';
        $enriched['can_cancel'] = in_array($subscription->status, ['active', 'on-hold', 'pending']);

        // Format billing info
        $period_labels = [
            'day' => __('day', 'woonoow'),
            'week' => __('week', 'woonoow'),
            'month' => __('month', 'woonoow'),
            'year' => __('year', 'woonoow'),
        ];
        $interval = $subscription->billing_interval > 1 ? $subscription->billing_interval . ' ' : '';
        $period = $period_labels[$subscription->billing_period] ?? $subscription->billing_period;
        if ($subscription->billing_interval > 1) {
            $period .= 's'; // Pluralize
        }
        $enriched['billing_schedule'] = sprintf(__('Every %s%s', 'woonoow'), $interval, $period);

        // Add payment method title
        $payment_title = $subscription->payment_method; // Default to ID

        // 1. Try from payment_meta (stored snapshot)
        if (!empty($subscription->payment_meta)) {
            $meta = json_decode($subscription->payment_meta, true);
            if (isset($meta['method_title']) && !empty($meta['method_title'])) {
                $payment_title = $meta['method_title'];
            }
        }

        // 2. If it looks like an ID (no spaces, lowercase), try to get fresh title from gateway
        if ($payment_title === $subscription->payment_method && function_exists('WC')) {
            $gateways_handler = WC()->payment_gateways();
            if ($gateways_handler) {
                $gateways = $gateways_handler->payment_gateways();
                if (isset($gateways[$subscription->payment_method])) {
                    $gw = $gateways[$subscription->payment_method];
                    $payment_title = $gw->get_title() ?: $gw->method_title;
                }
            }
        }

        $enriched['payment_method_title'] = $payment_title;

        return $enriched;
    }
}
