<?php
/**
 * Settings REST Controller
 *
 * @package Invizo\SubscriptionsLite\REST_API
 */

namespace Invizo\SubscriptionsLite\REST_API;

use Exception;
use Invizo\SubscriptionsLite\Gateway\StripeGateway;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Server;

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

class Settings_Controller extends WP_REST_Controller {

    public function __construct() {
        $this->namespace = 'invizo-subs/v1';
        $this->rest_base = 'settings';
    }

    public function register_routes() {
        register_rest_route( $this->namespace, '/' . $this->rest_base, array(
            array(
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => array( $this, 'get_items' ),
                'permission_callback' => array( $this, 'permissions_check' ),
            ),
            array(
                'methods'             => WP_REST_Server::EDITABLE,
                'callback'            => array( $this, 'update_items' ),
                'permission_callback' => array( $this, 'permissions_check' ),
            ),
        ) );
        
        register_rest_route( $this->namespace, '/' . $this->rest_base . '/generate-standalone-pages', array(
            array(
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => array( $this, 'generate_standalone_pages' ),
                'permission_callback' => array( $this, 'permissions_check' ),
            ),
        ) );

        register_rest_route( $this->namespace, '/' . $this->rest_base . '/webhook', array(
            array(
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => array( $this, 'auto_setup_webhook' ),
                'permission_callback' => array( $this, 'permissions_check' ),
            ),
        ) );
        
        register_rest_route( $this->namespace, '/' . $this->rest_base . '/onboarding-complete', array(
            array(
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => array( $this, 'complete_onboarding' ),
                'permission_callback' => array( $this, 'permissions_check' ),
            ),
        ) );
    }

    public function permissions_check( $request ) {
        return current_user_can( 'manage_options' );
    }

    public function get_items( $request ) {
        StripeGateway::maybe_migrate_legacy_stripe_keys();

        $stripe_test_public = get_option( 'invizo_stripe_test_public_key', '' );
        $stripe_test_secret = get_option( 'invizo_stripe_test_secret_key', '' );
        $stripe_live_public = get_option( 'invizo_stripe_live_public_key', '' );
        $stripe_live_secret = get_option( 'invizo_stripe_live_secret_key', '' );
        $stripe_mode        = get_option( 'invizo_stripe_mode', 'test' );
        $stripe_active_pub  = $stripe_mode === 'live' ? $stripe_live_public : $stripe_test_public;
        $stripe_active_sec  = $stripe_mode === 'live' ? $stripe_live_secret : $stripe_test_secret;

        $checkout_page_id  = (int) get_option( 'invizo_standalone_checkout_page_id', 0 );
        $subs_page_id      = (int) get_option( 'invizo_standalone_subscriptions_page_id', 0 );
        $store_page_id     = (int) get_option( 'invizo_standalone_store_page_id', 0 );
        $account_page_id   = (int) get_option( 'invizo_standalone_account_page_id', 0 );
        $login_page_id     = (int) get_option( 'invizo_standalone_login_page_id', 0 );
        $register_page_id  = (int) get_option( 'invizo_standalone_register_page_id', 0 );
        $privacy_page_id   = (int) get_option( 'invizo_standalone_privacy_policy_page_id', 0 );

        $page_choices = array();
        foreach ( get_pages(
            array(
                'sort_column' => 'post_title',
                'sort_order'  => 'ASC',
                'post_status' => 'publish',
            )
        ) as $p ) {
            $page_choices[] = array(
                'id'    => (int) $p->ID,
                'title' => $p->post_title,
            );
        }

        return rest_ensure_response( array(
            'stripe_test_public'  => $stripe_test_public,
            'stripe_test_secret'  => $stripe_test_secret,
            'stripe_live_public'  => $stripe_live_public,
            'stripe_live_secret'  => $stripe_live_secret,
            'stripe_public'       => $stripe_active_pub,
            'stripe_secret'       => $stripe_active_sec,
            'stripe_mode'         => $stripe_mode,
            'engine_mode'   => get_option( 'invizo_engine_mode', 'standalone' ),
            'webhook_url'   => StripeGateway::get_webhook_url(),
            'webhook_secret'   => get_option( 'invizo_stripe_webhook_secret', '' ),
            'paypal_client_id' => get_option( 'invizo_paypal_client_id', '' ),
            'paypal_secret'    => get_option( 'invizo_paypal_secret', '' ),
            'paypal_mode'      => get_option( 'invizo_paypal_mode', 'test' ),
            'openai_key'       => get_option( 'invizo_openai_key', '' ),
            'standalone_subscriptions_page_id' => $subs_page_id,
            'standalone_subscriptions_page_url' => $subs_page_id ? get_permalink( $subs_page_id ) : '',
            'standalone_store_page_id' => $store_page_id,
            'standalone_store_page_url' => $store_page_id ? get_permalink( $store_page_id ) : '',
            'standalone_account_page_id' => $account_page_id,
            'standalone_account_page_url' => $account_page_id ? get_permalink( $account_page_id ) : '',
            'standalone_login_page_id' => $login_page_id,
            'standalone_login_page_url' => $login_page_id ? get_permalink( $login_page_id ) : '',
            'standalone_register_page_id' => $register_page_id,
            'standalone_register_page_url' => $register_page_id ? get_permalink( $register_page_id ) : '',
            'standalone_checkout_page_id' => $checkout_page_id,
            'standalone_checkout_page_url' => $checkout_page_id ? get_permalink( $checkout_page_id ) : '',
            'standalone_privacy_policy_page_id' => $privacy_page_id,
            'standalone_privacy_policy_page_url' => $privacy_page_id ? get_permalink( $privacy_page_id ) : '',
            'standalone_default_pages_created' => get_option( 'invizo_standalone_default_pages_created', '0' ) === '1',
            'checkout_btn_subscribe'   => get_option( 'invizo_checkout_btn_subscribe', 'Subscribe Now' ),
            'checkout_btn_processing'  => get_option( 'invizo_checkout_btn_processing', 'Processing...' ),
            'require_subscription_email_verification' => get_option( 'invizo_sub_require_email_verification', '0' ) === '1',
            'checkout_page_choices'    => $page_choices,
        ) );
    }

    public function update_items( $request ) {
        StripeGateway::maybe_migrate_legacy_stripe_keys();

        $engine = sanitize_text_field( $request->get_param( 'engine_mode' ) );
        $pp_client = sanitize_text_field( $request->get_param( 'paypal_client_id' ) );
        $pp_secret = sanitize_text_field( $request->get_param( 'paypal_secret' ) );
        $pp_mode = sanitize_text_field( $request->get_param( 'paypal_mode' ) );
        $openai = sanitize_text_field( $request->get_param( 'openai_key' ) );

        if ( $request->has_param( 'stripe_mode' ) ) {
            $mode = sanitize_text_field( $request->get_param( 'stripe_mode' ) );
            update_option( 'invizo_stripe_mode', $mode === 'live' ? 'live' : 'test' );
        }

        $has_split = $request->has_param( 'stripe_test_public' ) || $request->has_param( 'stripe_live_public' );

        if ( $has_split ) {
            if ( $request->has_param( 'stripe_test_public' ) ) {
                update_option( 'invizo_stripe_test_public_key', sanitize_text_field( $request->get_param( 'stripe_test_public' ) ) );
            }
            if ( $request->has_param( 'stripe_test_secret' ) ) {
                update_option( 'invizo_stripe_test_secret_key', sanitize_text_field( $request->get_param( 'stripe_test_secret' ) ) );
            }
            if ( $request->has_param( 'stripe_live_public' ) ) {
                update_option( 'invizo_stripe_live_public_key', sanitize_text_field( $request->get_param( 'stripe_live_public' ) ) );
            }
            if ( $request->has_param( 'stripe_live_secret' ) ) {
                update_option( 'invizo_stripe_live_secret_key', sanitize_text_field( $request->get_param( 'stripe_live_secret' ) ) );
            }
        } elseif ( $request->has_param( 'stripe_public' ) || $request->has_param( 'stripe_secret' ) ) {
            $cur_mode = get_option( 'invizo_stripe_mode', 'test' );
            if ( $request->has_param( 'stripe_public' ) ) {
                $p = sanitize_text_field( $request->get_param( 'stripe_public' ) );
                if ( $cur_mode === 'live' ) {
                    update_option( 'invizo_stripe_live_public_key', $p );
                } else {
                    update_option( 'invizo_stripe_test_public_key', $p );
                }
            }
            if ( $request->has_param( 'stripe_secret' ) ) {
                $s = sanitize_text_field( $request->get_param( 'stripe_secret' ) );
                if ( $cur_mode === 'live' ) {
                    update_option( 'invizo_stripe_live_secret_key', $s );
                } else {
                    update_option( 'invizo_stripe_test_secret_key', $s );
                }
            }
        }
        
        if ( ! empty( $engine ) ) {
            update_option( 'invizo_engine_mode', $engine === 'woocommerce' ? 'woocommerce' : 'standalone' );
        }
        
        if ( $request->has_param( 'paypal_client_id' ) || $request->has_param( 'paypal_secret' ) || $request->has_param( 'paypal_mode' ) ) {
            update_option( 'invizo_paypal_client_id', $pp_client );
            update_option( 'invizo_paypal_secret', $pp_secret );
            update_option( 'invizo_paypal_mode', $pp_mode === 'live' ? 'live' : 'test' );
        }
        
        if ( $request->has_param( 'openai_key' ) ) {
            update_option( 'invizo_openai_key', $openai );
        }

        if ( $request->has_param( 'standalone_subscriptions_page_id' ) ) {
            $subs_id = absint( $request->get_param( 'standalone_subscriptions_page_id' ) );
            update_option( 'invizo_standalone_subscriptions_page_id', $subs_id );
        }

        if ( $request->has_param( 'standalone_checkout_page_id' ) ) {
            $page_id = absint( $request->get_param( 'standalone_checkout_page_id' ) );
            update_option( 'invizo_standalone_checkout_page_id', $page_id );
        }

        if ( $request->has_param( 'standalone_store_page_id' ) ) {
            update_option( 'invizo_standalone_store_page_id', absint( $request->get_param( 'standalone_store_page_id' ) ) );
        }

        if ( $request->has_param( 'standalone_account_page_id' ) ) {
            update_option( 'invizo_standalone_account_page_id', absint( $request->get_param( 'standalone_account_page_id' ) ) );
        }

        if ( $request->has_param( 'standalone_login_page_id' ) ) {
            update_option( 'invizo_standalone_login_page_id', absint( $request->get_param( 'standalone_login_page_id' ) ) );
        }

        if ( $request->has_param( 'standalone_register_page_id' ) ) {
            update_option( 'invizo_standalone_register_page_id', absint( $request->get_param( 'standalone_register_page_id' ) ) );
        }

        if ( $request->has_param( 'standalone_privacy_policy_page_id' ) ) {
            update_option( 'invizo_standalone_privacy_policy_page_id', absint( $request->get_param( 'standalone_privacy_policy_page_id' ) ) );
        }

        if ( $request->has_param( 'checkout_btn_subscribe' ) ) {
            update_option(
                'invizo_checkout_btn_subscribe',
                sanitize_text_field( $request->get_param( 'checkout_btn_subscribe' ) ) ?: 'Subscribe Now'
            );
        }

        if ( $request->has_param( 'checkout_btn_processing' ) ) {
            update_option(
                'invizo_checkout_btn_processing',
                sanitize_text_field( $request->get_param( 'checkout_btn_processing' ) ) ?: 'Processing...'
            );
        }

        if ( $request->has_param( 'require_subscription_email_verification' ) ) {
            $rv = $request->get_param( 'require_subscription_email_verification' );
            $on = ( $rv === true || $rv === 'true' || $rv === 1 || $rv === '1' );
            update_option( 'invizo_sub_require_email_verification', $on ? '1' : '0' );
        }

        $checkout_page_id  = (int) get_option( 'invizo_standalone_checkout_page_id', 0 );
        $subs_page_id      = (int) get_option( 'invizo_standalone_subscriptions_page_id', 0 );
        $store_page_id     = (int) get_option( 'invizo_standalone_store_page_id', 0 );
        $account_page_id   = (int) get_option( 'invizo_standalone_account_page_id', 0 );
        $login_page_id     = (int) get_option( 'invizo_standalone_login_page_id', 0 );
        $register_page_id  = (int) get_option( 'invizo_standalone_register_page_id', 0 );
        $privacy_page_id   = (int) get_option( 'invizo_standalone_privacy_policy_page_id', 0 );

        $stripe_test_public = get_option( 'invizo_stripe_test_public_key', '' );
        $stripe_test_secret = get_option( 'invizo_stripe_test_secret_key', '' );
        $stripe_live_public = get_option( 'invizo_stripe_live_public_key', '' );
        $stripe_live_secret = get_option( 'invizo_stripe_live_secret_key', '' );
        $stripe_mode_saved  = get_option( 'invizo_stripe_mode', 'test' );
        $stripe_active_pub  = $stripe_mode_saved === 'live' ? $stripe_live_public : $stripe_test_public;
        $stripe_active_sec  = $stripe_mode_saved === 'live' ? $stripe_live_secret : $stripe_test_secret;

        return rest_ensure_response( array(
            'message' => 'Settings saved successfully',
            'stripe_test_public'  => $stripe_test_public,
            'stripe_test_secret'  => $stripe_test_secret,
            'stripe_live_public'  => $stripe_live_public,
            'stripe_live_secret'  => $stripe_live_secret,
            'stripe_public'       => $stripe_active_pub,
            'stripe_secret'       => $stripe_active_sec,
            'stripe_mode'         => $stripe_mode_saved,
            'engine_mode' => $engine === 'woocommerce' ? 'woocommerce' : 'standalone',
            'paypal_client_id' => $pp_client,
            'paypal_secret' => $pp_secret,
            'paypal_mode' => $pp_mode === 'live' ? 'live' : 'test',
            'openai_key' => $openai,
            'standalone_subscriptions_page_id' => $subs_page_id,
            'standalone_subscriptions_page_url' => $subs_page_id ? get_permalink( $subs_page_id ) : '',
            'standalone_store_page_id' => $store_page_id,
            'standalone_store_page_url' => $store_page_id ? get_permalink( $store_page_id ) : '',
            'standalone_account_page_id' => $account_page_id,
            'standalone_account_page_url' => $account_page_id ? get_permalink( $account_page_id ) : '',
            'standalone_login_page_id' => $login_page_id,
            'standalone_login_page_url' => $login_page_id ? get_permalink( $login_page_id ) : '',
            'standalone_register_page_id' => $register_page_id,
            'standalone_register_page_url' => $register_page_id ? get_permalink( $register_page_id ) : '',
            'standalone_privacy_policy_page_id' => $privacy_page_id,
            'standalone_privacy_policy_page_url' => $privacy_page_id ? get_permalink( $privacy_page_id ) : '',
            'standalone_checkout_page_id' => $checkout_page_id,
            'standalone_checkout_page_url' => $checkout_page_id ? get_permalink( $checkout_page_id ) : '',
            'standalone_default_pages_created' => get_option( 'invizo_standalone_default_pages_created', '0' ) === '1',
            'checkout_btn_subscribe'  => get_option( 'invizo_checkout_btn_subscribe', 'Subscribe Now' ),
            'checkout_btn_processing' => get_option( 'invizo_checkout_btn_processing', 'Processing...' ),
            'require_subscription_email_verification' => get_option( 'invizo_sub_require_email_verification', '0' ) === '1',
        ) );
    }

    /**
     * Create default WordPress pages with Invizo shortcodes and save option IDs.
     *
     * @return array<string,int> Page keys => post IDs.
     */
    public static function ensure_default_standalone_pages() {
        $definitions = array(
            'store'    => array(
                'title'   => __( 'Subscription Plans', 'invizo-subscriptions-lite' ),
                'slug'    => 'invizo-subscription-plans',
                'content' => "[invizo_store]\n",
            ),
            'checkout' => array(
                'title'   => __( 'Checkout', 'invizo-subscriptions-lite' ),
                'slug'    => 'invizo-checkout',
                'content' => "[invizo_checkout]\n",
            ),
            'account'  => array(
                'title'   => __( 'My Account', 'invizo-subscriptions-lite' ),
                'slug'    => 'invizo-my-account',
                'content' => "[invizo_account]\n",
            ),
            'login'    => array(
                'title'   => __( 'Log In', 'invizo-subscriptions-lite' ),
                'slug'    => 'invizo-login',
                'content' => '[invizo_auth view="login"]' . "\n",
            ),
            'register' => array(
                'title'   => __( 'Register', 'invizo-subscriptions-lite' ),
                'slug'    => 'invizo-register',
                'content' => '[invizo_auth view="register"]' . "\n",
            ),
            'privacy'  => array(
                'title'   => __( 'Privacy Policy', 'invizo-subscriptions-lite' ),
                'slug'    => 'invizo-privacy-policy',
                'content' => '<p>' . esc_html__( 'Replace this text with your privacy policy.', 'invizo-subscriptions-lite' ) . '</p>',
            ),
        );

        $ids = array();
        foreach ( $definitions as $key => $def ) {
            $ids[ $key ] = self::get_or_create_standalone_page( $def['title'], $def['slug'], $def['content'] );
        }

        $assign_if_empty = static function ( $option, $post_id ) {
            $post_id = (int) $post_id;
            if ( $post_id <= 0 ) {
                return;
            }
            if ( (int) get_option( $option, 0 ) === 0 ) {
                update_option( $option, $post_id );
            }
        };

        $assign_if_empty( 'invizo_standalone_store_page_id', $ids['store'] );
        $assign_if_empty( 'invizo_standalone_checkout_page_id', $ids['checkout'] );
        $assign_if_empty( 'invizo_standalone_account_page_id', $ids['account'] );
        $assign_if_empty( 'invizo_standalone_login_page_id', $ids['login'] );
        $assign_if_empty( 'invizo_standalone_register_page_id', $ids['register'] );
        $assign_if_empty( 'invizo_standalone_privacy_policy_page_id', $ids['privacy'] );
        if ( (int) get_option( 'invizo_standalone_subscriptions_page_id', 0 ) === 0 ) {
            update_option( 'invizo_standalone_subscriptions_page_id', $ids['account'] );
        }

        $first_run = get_option( 'invizo_standalone_default_pages_created', '0' ) !== '1';
        if ( $first_run ) {
            update_option( 'users_can_register', '1' );
        }
        update_option( 'invizo_standalone_default_pages_created', '1' );

        return $ids;
    }

    /**
     * @param string $title   Page title.
     * @param string $slug    Post slug.
     * @param string $content Post content (shortcodes).
     * @return int Post ID or 0 on failure.
     */
    protected static function get_or_create_standalone_page( $title, $slug, $content ) {
        $existing = get_page_by_path( $slug, OBJECT, 'page' );
        if ( $existing && $existing->post_status === 'publish' ) {
            return (int) $existing->ID;
        }

        $post_id = wp_insert_post(
            array(
                'post_title'   => $title,
                'post_name'    => $slug,
                'post_content' => $content,
                'post_status'  => 'publish',
                'post_type'    => 'page',
            ),
            true
        );

        if ( is_wp_error( $post_id ) ) {
            return 0;
        }

        return (int) $post_id;
    }

    /**
     * @param WP_REST_Request $request Request.
     * @return WP_REST_Response|WP_Error
     */
    public function generate_standalone_pages( $request ) {
        $engine = get_option( 'invizo_engine_mode', 'standalone' );
        if ( $engine !== 'standalone' ) {
            return new WP_Error(
                'not_standalone',
                __( 'Switch to standalone mode under General, save, then run this again.', 'invizo-subscriptions-lite' ),
                array( 'status' => 400 )
            );
        }

        self::ensure_default_standalone_pages();

        return $this->get_items( $request );
    }

    public function auto_setup_webhook( $request ) {
        $keys = StripeGateway::get_api_keys();
        if ( empty( $keys['secret'] ) ) {
            return new WP_Error( 'no_key', 'Please save a Stripe Secret Key for the current mode first.', array( 'status' => 400 ) );
        }

        if ( ! StripeGateway::load_sdk() ) {
            return new WP_Error( 'no_sdk', 'Stripe SDK not available.', array( 'status' => 500 ) );
        }

        \InvizoSubscriptionsLiteVendor\Stripe\Stripe::setApiKey( $keys['secret'] );

        $webhook_url = StripeGateway::get_webhook_url();

        try {
            $endpoint = \InvizoSubscriptionsLiteVendor\Stripe\WebhookEndpoint::create([
                'url' => $webhook_url,
                'enabled_events' => [
                    'invoice.payment_succeeded',
                    'invoice.payment_failed',
                    'customer.subscription.deleted',
                    'customer.subscription.updated',
                ],
            ]);

            update_option( 'invizo_stripe_webhook_secret', $endpoint->secret );

            return rest_ensure_response( array(
                'message' => 'Webhook registered automatically!',
                'webhook_secret' => $endpoint->secret
            ) );
        } catch ( Exception $e ) {
            return new WP_Error( 'stripe_error', $e->getMessage(), array( 'status' => 500 ) );
        }
    }

    public function complete_onboarding( $request ) {
        $engine = sanitize_text_field( $request->get_param( 'engine_mode' ) );
        $telemetry = rest_sanitize_boolean( $request->get_param( 'telemetry' ) );
        $create_plan = rest_sanitize_boolean( $request->get_param( 'create_test_plan' ) );

        if ( ! empty( $engine ) ) {
            update_option( 'invizo_engine_mode', $engine === 'woocommerce' ? 'woocommerce' : 'standalone' );
        }
        update_option( 'invizo_allow_telemetry', $telemetry ? '1' : '0' );

        if ( $create_plan ) {
            $plan_id = wp_insert_post( array(
                'post_type'   => 'invizo_plan',
                'post_title'  => 'Pro Subscription',
                'post_status' => 'publish',
            ) );
            if ( ! is_wp_error( $plan_id ) ) {
                update_post_meta( $plan_id, '_price', '10.00' );
                update_post_meta( $plan_id, '_interval', 'month' );
                update_post_meta( $plan_id, '_trial_days', '0' );
                update_post_meta( $plan_id, '_features', "Premium Support\nAll Extensions\nUnlimited Pages" );
            }
        }

        update_option( 'invizo_onboarding_completed', '1' );

        return rest_ensure_response( array( 'success' => true ) );
    }
}
