<?php
namespace OxygenApp\Controllers;

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

use OxygenApp\Common\Guards\Guards;
use OxygenApp\Common\Guards\SignupGuard;
use OxygenApp\Common\Guards\ActivateResetGuard;
use OxygenApp\Models\User;
use OxygenApp\Config\Config;
use OxygenApp\Utils\OptionUtils;
use OxygenApp\Common\Guards\ResetPasswordRequestGuard;
use OxygenApp\Common\Guards\ResetPasswordGuard;
use OxygenApp\Common\Guards\UserBackgroundGuard;
use OxygenApp\Common\Guards\LoginGuard;
use OxygenApp\Utils\UserUtil;
use OxygenApp\Utils\Sanitizer;

class UserCtrl {

    static function create(\WP_REST_Request $request): \WP_REST_Response {
        
        $guardResult = Guards::use($request, SignupGuard::class);
        if ($guardResult !== true) {
            return $guardResult;
        }

        $activation_code = wp_generate_password(30, false);
        $email = $request->get_param('email');

        $user = new User();
        $userExists = $user->find('email', $email);
        if ($userExists) {
            return new \WP_REST_Response(['message' => esc_html__('User exists. Please log in.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $result = $user->create([
            'email' => $email,
            'password' => $request->get_param('password'),
            'terms' => $request->get_param('terms'),
            'activation_code' => $activation_code,
        ]);

        if (!$result) {
            return new \WP_REST_Response([], 400);
        }

        $activationLink = rtrim(get_rest_url(), '/') . '/' . ltrim(Config::getInstance()->getSetting('app_rest_namespace'), '/') . "/activate?code=" . urlencode($activation_code);

        do_action('oxygen_action_user_register', [
            'userEmail' => $email,
            'activationLink' => $activationLink
        ]);

        return new \WP_REST_Response([], 200);
    }

    static function resendActivation(\WP_REST_Request $request): \WP_REST_Response {
        $guardResult = Guards::use($request, ResetPasswordRequestGuard::class);
        if ($guardResult !== true) {
            return $guardResult;
        }

        $email = $request->get_param('email');
        $user = new User();
        $userResult = $user->find('email', $email);
        if (!$userResult) {
            return new \WP_REST_Response(['message' => esc_html__('User does not exists.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $is_active = $userResult['is_active'] ?? false;
        if ($is_active) {
            return new \WP_REST_Response(['message' => esc_html__('The account is already active.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $activation_code = wp_generate_password(30, false);
        $updated = $user->update($userResult['id'], [
            'activation_code' => $activation_code
        ]);

        if (!$updated) {
            return new \WP_REST_Response(['message' => esc_html__('Something went wrong.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $activationLink = rtrim(get_rest_url(), '/') . '/' . ltrim(Config::getInstance()->getSetting('app_rest_namespace'), '/') . "/activate?code=" . urlencode($activation_code);

        do_action('oxygen_action_user_register', [
            'userEmail' => $email,
            'activationLink' => $activationLink
        ]);


        return new \WP_REST_Response([], 200);
    }

    static function activate(\WP_REST_Request $request) {

        $routes = Config::getInstance()->getFrontendRoutes();
        $isHomepageApp = OptionUtils::getInstance()->getOption('is_homepage_app');
        $baseRedirect = '';
        if ($isHomepageApp) {
            $baseRedirect = rtrim(site_url(), '/');
        } else {
            $appPageId = OptionUtils::getInstance()->getOption('app_page_id');
            $baseRedirect = rtrim(get_the_permalink($appPageId), '/');
        }

        $guardResult = Guards::use($request, ActivateResetGuard::class);
        if ($guardResult !== true) {
            wp_safe_redirect($baseRedirect . '/#' . ($routes['error']['hash'] ?? '') . '?action=missing_activation');
            exit();
        }

        $code = $request->get_param('code');
        $user = new User();
        $codeResult = $user->find('activation_code', $code);
        if (!$codeResult) {
            wp_safe_redirect($baseRedirect . '/#' . ($routes['error']['hash'] ?? '') . '?action=missing_activation');
            exit();
        }

        $userId = $codeResult['id'] ?? '';
        $updateResult = $user->update($userId, [
            'activation_code' => '',
            'is_active' => 1
        ]);

        if (!$updateResult) {
            wp_safe_redirect($baseRedirect . '/#' . ($routes['error']['hash'] ?? '') . '?action=missing_activation');
            exit();
        }

        wp_safe_redirect($baseRedirect . '/#' . ($routes['success']['hash'] ?? '') . '?action=activated');
        exit();
    }

    static function resetPasswordRequest(\WP_REST_Request $request): \WP_REST_Response {
        $guardResult = Guards::use($request, ResetPasswordRequestGuard::class);
        if ($guardResult !== true) {
            return $guardResult;
        }

        $email = $request->get_param('email');

        $user = new User();
        $userData = $user->find('email', $email);
        if (!$userData) {
            return new \WP_REST_Response(['message' => esc_html__('User does not exists.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $resetToken = wp_generate_password(30, false);
        $userId = $userData['id'] ?? '';
        $updated = $user->update($userId, [
            'reset_token' => $resetToken
        ]);

        if (!$updated) {
            return new \WP_REST_Response(['message' => esc_html__('Can not generate reset token.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $isHomepageApp = OptionUtils::getInstance()->getOption('is_homepage_app');
        $baseRedirect = '';
        if ($isHomepageApp) {
            $baseRedirect = rtrim(site_url(), '/');
        } else {
            $appPageId = OptionUtils::getInstance()->getOption('app_page_id');
            $baseRedirect = rtrim(get_the_permalink($appPageId), '/');
        }

        $routes = Config::getInstance()->getFrontendRoutes();
        $resetLink = $baseRedirect . '/#' . ($routes['reset_password']['hash'] ?? '') . '?code=' . urlencode($resetToken);

        do_action('oxygen_app_action_user_reset_password', [
            'userEmail' => $email,
            'resetLink' => $resetLink
        ]);

        return new \WP_REST_Response([], 200);
    }

    static function resetPassword(\WP_REST_Request $request): \WP_REST_Response {
        $guardResult = Guards::use($request, ResetPasswordGuard::class);
        if ($guardResult !== true) {
            return $guardResult;
        }

        $code = $request->get_param('code');

        $user = new User();
        $userData = $user->find('reset_token', $code);
        if (!$userData) {
            return new \WP_REST_Response(['message' => esc_html__('Invalid reset token.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        $userId = $userData['id'] ?? '';
        $updated = $user->update($userId, [
            'reset_token' => wp_generate_password(30, false),
            'password' => $request->get_param('password')
        ]);

        if (!$updated) {
            return new \WP_REST_Response(['message' => esc_html__('Something went wrong.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        return new \WP_REST_Response([], 200);
    }

    static function login(\WP_REST_Request $request): \WP_REST_Response {

        $guardResult = Guards::use($request, LoginGuard::class);
        if ($guardResult !== true) {
            return $guardResult;
        }

        $email = $request->get_param('email');
        $password = $request->get_param('password');

        $user = new User();
        $userData = $user->find('email', $email);
        if (!$userData) {
            return new \WP_REST_Response(['message' => esc_html__('User does not exists.', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        if (!wp_check_password($password, $userData['password'] ?? '', $userData['id'] ?? '')) {
            return new \WP_REST_Response(['message' => esc_html__('Incorrect user or password', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }


        if ((int) ($userData['is_active'] ?? 0) === 0) {
            return new \WP_REST_Response(['message' => esc_html__('Account not activated', 'oxyleaf-app-working-and-relaxing-app')], 400);
        }

        // update last login time
        $user->update($userData['id'], [
            'last_login_time' => current_time('mysql', true)
        ]);

        // set session
        UserUtil::login($userData);

        return new \WP_REST_Response(UserUtil::getInstance()->getUserFromSession(), 200);
    }

    static function logout(\WP_REST_Request $request): \WP_REST_Response {
        UserUtil::logout();
        return new \WP_REST_Response([]);
    }

    static function isLoggedIn(\WP_REST_Request $request): \WP_REST_Response {
        return new \WP_REST_Response([
            'loggedin' => UserUtil::isLoggedIn()
        ]);
    }

    static function updateBackground(\WP_REST_Request $request): \WP_REST_Response {

        $background = $request->get_param('background');
        $bid = $background['bid'] ?? null;

        $userSessionData = UserUtil::getInstance()->getUserFromSession();
        $user_id = $userSessionData['user_id'] ?? '';
        $user = new User();

        if (is_numeric($bid)) {
            $guardResult = Guards::use($request, UserBackgroundGuard::class);
            if ($guardResult !== true) {
                return $guardResult;
            }

            $user->updateUserMeta($user_id, 'userbackgroundid', Sanitizer::sanitize_data($bid));
        } else {
            // delete existing user background
            $user->updateUserMeta($user_id, 'userbackgroundid', -1);
        }

        return new \WP_REST_Response(['message' => esc_html__('success', 'oxyleaf-app-working-and-relaxing-app')]);
    }

    static function search(): void {
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'oxyleaf_app_settings_nonce')) {
            wp_send_json_error(['message' => esc_html__('Security check failed', 'oxyleaf-app-working-and-relaxing-app')], 403);
            return;
        }

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'oxyleaf-app-working-and-relaxing-app')], 403);
            return;
        }

        $params = isset($_POST['params']) ? Sanitizer::sanitize_data(sanitize_text_field(wp_unslash($_POST['params']))) : [];

        $searchParams = [];

        if (isset($params['page'])) {
            $searchParams['page'] = max(1, absint($params['page']));
        }

        if (isset($params['per_page'])) {
            $searchParams['per_page'] = max(1, min(100, absint($params['per_page'])));
        }

        $userModel = new User();
        $result = $userModel->search($searchParams);

        wp_send_json_success([
            'data' => $result['data'] ?? [],
            'pagination' => $result['pagination'] ?? []
        ]);
    }

    static function updateUserField(): void {

        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'oxyleaf_app_settings_nonce')) {
            wp_send_json_error(['message' => esc_html__('Security check failed', 'oxyleaf-app-working-and-relaxing-app')], 403);
            return;
        }

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'oxyleaf-app-working-and-relaxing-app')], 403);
            return;
        }

        $userId = isset($_POST['user_id']) ? absint($_POST['user_id']) : 0;
        $field = isset($_POST['field']) ? sanitize_text_field(wp_unslash($_POST['field'])) : '';
        $value = isset($_POST['value']) ? absint($_POST['value']) : 0;

        if (empty($userId)) {
            wp_send_json_error(['message' => esc_html__('Invalid user ID', 'oxyleaf-app-working-and-relaxing-app')], 400);
            return;
        }

        $allowedFields = ['block_user'];
        if (!in_array($field, $allowedFields, true)) {
            wp_send_json_error(['message' => esc_html__('Invalid field', 'oxyleaf-app-working-and-relaxing-app')], 400);
            return;
        }

        if (!in_array($value, [0, 1], true)) {
            wp_send_json_error(['message' => esc_html__('Invalid value', 'oxyleaf-app-working-and-relaxing-app')], 400);
            return;
        }

        $userModel = new User();

        $user = $userModel->findById($userId);
        if (!$user) {
            wp_send_json_error(['message' => esc_html__('User not found', 'oxyleaf-app-working-and-relaxing-app')], 404);
            return;
        }

        $updated = $userModel->update($userId, [
            $field => $value
        ]);

        if ($updated === false) {
            wp_send_json_error(['message' => esc_html__('Failed to update user', 'oxyleaf-app-working-and-relaxing-app')], 500);
            return;
        }

        $fieldLabel = 'Blocked';
        $statusLabel = $value === 1 ? 'On' : 'Off';

        wp_send_json_success([
            'message' => sprintf(
                // translators: %1$s is the field label, %2$s is the status ("On" or "Off")
                esc_html__('%1$s status updated to %2$s', 'oxyleaf-app-working-and-relaxing-app'),
                $fieldLabel,
                $statusLabel
            ),
            'user_id' => $userId,
            'field' => $field,
            'value' => $value
        ]);
    }

    static function deleteUser(): void {
        if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'oxyleaf_app_settings_nonce')) {
            wp_send_json_error(['message' => esc_html__('Security check failed', 'oxyleaf-app-working-and-relaxing-app')], 403);
            return;
        }

        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'oxyleaf-app-working-and-relaxing-app')], 403);
            return;
        }

        $userId = isset($_POST['user_id']) ? absint($_POST['user_id']) : 0;

        if (empty($userId)) {
            wp_send_json_error(['message' => esc_html__('Invalid user ID', 'oxyleaf-app-working-and-relaxing-app')], 400);
            return;
        }

        $userModel = new User();
        $user = $userModel->findById($userId);

        if (!$user) {
            wp_send_json_error(['message' => esc_html__('User not found', 'oxyleaf-app-working-and-relaxing-app')], 404);
            return;
        }

        global $wpdb;
        $table = $wpdb->prefix . User::TABLE_NAME;
        $deleted = $wpdb->delete($table, ['id' => $userId], ['%d']);

        if ($deleted === false) {
            wp_send_json_error(['message' => esc_html__('Failed to delete user', 'oxyleaf-app-working-and-relaxing-app')], 500);
            return;
        }

        wp_send_json_success([
            'message' => sprintf(
                // translators: %s is the email address of the deleted user
                esc_html__('User "%s" has been deleted successfully', 'oxyleaf-app-working-and-relaxing-app'),
                $user['email']
            ),
            'user_id' => $userId
        ]);
    }

    static function deleteOwnAccount(\WP_REST_Request $request): \WP_REST_Response {
        // Get current user ID
        $userId = UserUtil::getCurrentUserId();

        if (!$userId) {
            return new \WP_REST_Response([
                'error' => esc_html__('User not authenticated', 'oxyleaf-app-working-and-relaxing-app')
            ], 401);
        }

        $user = new User();
        $userData = $user->findById($userId);

        if (!$userData) {
            return new \WP_REST_Response([
                'error' => esc_html__('User not found', 'oxyleaf-app-working-and-relaxing-app')
            ], 404);
        }

        // Delete user data from custom table
        global $wpdb;
        $table = $wpdb->prefix . User::TABLE_NAME;

        $deleted = $wpdb->delete(
            $table,
            ['id' => $userId],
            ['%d']
        );

        if ($deleted === false) {
            return new \WP_REST_Response([
                'error' => esc_html__('Failed to delete account', 'oxyleaf-app-working-and-relaxing-app')
            ], 500);
        }

        // Clear user session
        UserUtil::logout();

        // Fire action to be used within plugin extended version
        do_action('oxygen_app_user_account_deleted', [
            'user_id' => $userId,
            'email' => $userData['user_email']
        ]);

        return new \WP_REST_Response([
            'success' => true,
            'message' => esc_html__('Account deleted successfully', 'oxyleaf-app-working-and-relaxing-app')
        ], 200);
    }

    static function updateUserMeta(\WP_REST_Request $request): \WP_REST_Response {
        $userId = UserUtil::getCurrentUserId();

        if (!$userId) {
            return new \WP_REST_Response([
                'error' => esc_html__('User not authenticated', 'oxyleaf-app-working-and-relaxing-app')
            ], 401);
        }

        $metaKey = $request->get_param('meta_key');
        $metaValue = $request->get_param('meta_value');

        if (empty($metaKey)) {
            return new \WP_REST_Response([
                'error' => esc_html__('Meta key is required', 'oxyleaf-app-working-and-relaxing-app')
            ], 400);
        }

        $allowedMetaKeys = [
            'show_user_time_date', 'daily_sleep_time_enabled', 'daily_sleep_time'
        ];

        if (!in_array($metaKey, $allowedMetaKeys, true)) {
            return new \WP_REST_Response([
                'error' => esc_html__('Invalid meta key', 'oxyleaf-app-working-and-relaxing-app')
            ], 400);
        }

        $metaKey = Sanitizer::sanitize_data($metaKey);
        $metaValue = Sanitizer::sanitize_data($metaValue);

        $user = new User();
        $result = $user->updateUserMeta($userId, $metaKey, $metaValue);

        if ($result === false) {
            return new \WP_REST_Response([
                'error' => esc_html__('Failed to update user meta', 'oxyleaf-app-working-and-relaxing-app')
            ], 500);
        }

        return new \WP_REST_Response([
            'success' => true,
            'message' => esc_html__('User setting updated successfully', 'oxyleaf-app-working-and-relaxing-app'),
            'meta_key' => $metaKey,
            'meta_value' => $metaValue
        ], 200);
    }

}
