<?php
// phpcs:ignoreFile WordPress.Security.EscapeOutput.OutputNotEscaped
class SLN_Shortcode_Salon_DetailsStep extends SLN_Shortcode_Salon_AbstractUserStep
{
    public function isValid()
    {
        if ($this->isSkipCheckoutWhenLoggedInEnabled() && is_user_logged_in() && $this->loggedInUserHasAllRequiredFields()) {
            wp_get_current_user();
            $customer_fields = SLN_Enum_CheckoutFields::forRegistration()->appendSmsPrefix();
            $values = array();
            if ($customer_fields) {
                foreach ($customer_fields as $key => $field) {
                    $values[$key] = $field->getValue(get_current_user_id());
                }
            }
            $this->bindValues($values);
            $_SESSION['sln_sms_dontcheck'] = true;
            SLN_Plugin::addLog('[Details Step] Logged-in user has all required fields - auto-skipping step');
            return true;
        }

        return parent::isValid();
    }

    /**
     * Whether the "Skip the checkout form if user is logged-in" checkout option
     * is enabled.
     *
     * Backward compatibility: before this option existed the checkout step was
     * always auto-skipped for logged-in users with complete profiles, so a value
     * that was never saved (null) is treated as enabled.
     *
     * @return bool
     */
    private function isSkipCheckoutWhenLoggedInEnabled()
    {
        $value = $this->getPlugin()->getSettings()->get('skip_checkout_if_logged_in');

        return $value === null ? true : (bool) $value;
    }

    private function loggedInUserHasAllRequiredFields()
    {
        $fields = SLN_Enum_CheckoutFields::forDetailsStep();
        $userId = get_current_user_id();
        foreach ($fields as $key => $field) {
            if ($field->isRequiredNotHidden()) {
                $value = $field->getValue($userId);
                if (empty($value)) {
                    return false;
                }
            }
        }
        return true;
    }

    protected function dispatchForm()
    {
        global $current_user;
        
        // DEFENSIVE CHECK (Feb 10, 2026): Ensure logged-in users have their data bound
        // This catches the case where a logged-in user submits the details form
        // but their data wasn't properly loaded in isValid()
        if (is_user_logged_in() && empty($_POST['sln'])) {
            // User is logged in but didn't fill form (auto-submit or skip scenario)
            // Ensure their data is in BookingBuilder
            $bb = $this->getPlugin()->getBookingBuilder();
            $hasData = !empty($bb->get('firstname')) || !empty($bb->get('email'));
            
            if (!$hasData) {
                SLN_Plugin::addLog('[Details Step] Logged-in user missing data in dispatchForm, loading now...');
                $customer_fields = SLN_Enum_CheckoutFields::forRegistration()->appendSmsPrefix();
                $values = array();
                
                foreach ($customer_fields as $key => $field) {
                    $values[$key] = $field->getValue(get_current_user_id());
                }
                
                $this->bindValues($values);
                SLN_Plugin::addLog('[Details Step] Customer data loaded and bound in dispatchForm');
            }
        }

	if (isset($_GET['sln_action']) && $_GET['sln_action'] === 'fb_login' && $this->getPlugin()->getSettings()->get('enabled_fb_login')) {

	    if (isset($_GET['code'])) {

            $accessToken = SLN_Helper_FacebookLogin::getAccessTokenByCode($_GET['code']);

            $tmp_values = $this->dispatchAuthFB($accessToken);

            if ( ! $this->hasErrors() ) {
                $update = [
                    'ID' => $current_user->ID,
                ];
                if(isset($values['firstname'])){
                    $update['first_name'] = $tmp_values['firstname'];
                }
                if(isset($values['lastname'])){
                    $update['last_name'] = $tmp_values['lastname'];
                }
                wp_update_user( $update );
            }

            $_SESSION['fb_access_token'] = $accessToken;

            $redirectUrl = isset($_GET['state']) ? $_GET['state'] : '';

            wp_redirect($redirectUrl);

            exit();
	    }

	    $redirectUrl = isset($_GET['referrer']) ? urlencode($_GET['referrer']) : '';
	    $fbLoginUrl  = SLN_Helper_FacebookLogin::getFacebookLoginUrl($redirectUrl);

	    wp_redirect($fbLoginUrl);

	    exit();
	}

	    if (isset($_SESSION['fb_access_token'])) {

		$tmp_values = $this->dispatchAuthFB($_SESSION['fb_access_token']);

		if ($this->hasErrors()) {
		    return false;
		}
    		$update = [
                'ID' => $current_user->ID,
            ];
            if(isset($values['firstname'])){
                $update['first_name'] = $tmp_values['firstname'];
            }
            if(isset($values['lastname'])){
                $update['last_name'] = $tmp_values['lastname'];
            }
            wp_update_user( $update );

		$values = array(
		    'fb_id' => $tmp_values['fb_id'],
		);

            foreach ( SLN_Enum_CheckoutFields::defaults() as $key => $field){
                if(!$field->isHidden()){
                    $values[$key] = $tmp_values[$key];
		}
		}

		do_action('sln.shortcode.details.dispatchForm.after_fb_login', $values, $this);

		unset($_SESSION['fb_access_token']);

	    } elseif (isset($_POST['login_name'])) {
            $ret = $this->dispatchAuth(sanitize_text_field(wp_unslash($_POST['login_name'])),sanitize_text_field($_POST['login_password']));
            if (!$ret) {
                return false;
            }

            foreach ( SLN_Enum_CheckoutFields::forRegistration()->appendSmsPrefix() as $key => $field){
                $values[$key] = $field->getValue(get_current_user_id());
            }

	    do_action('sln.shortcode.details.dispatchForm.after_login', $values, $this);
            $this->bindValues($values);
            $this->validate($values);
            if ($this->getErrors()) {
                $this->bindValues($values);
                return false;
            }else{
                $_SESSION['sln_sms_dontcheck'] = true;
            }
        } else {

            if ( empty( $_POST['sln'] ) ) {
                return false;
            }

            $values = $_POST['sln'];
            $this->bindValues($values);
            if (!is_user_logged_in()) {
                unset($_SESSION['sln_detail_step_need_register_user']);
                $this->validate($values);
                if ($this->getErrors()) {
                    return false;
                }

                if ($this->getPlugin()->getSettings()->get('enabled_force_guest_checkout') || $this->getPlugin()->getSettings()->get('enabled_guest_checkout') && isset($values['no_user_account']) && $values['no_user_account']) {
                    $_SESSION['sln_detail_step'] = $values;
		            do_action('sln.shortcode.details.dispatchForm.guest_checkout', $values, $this);
                } else {
                    if (email_exists($values['email'])) {
                        $this->addError(__('E-mail exists', 'salon-booking-system'));
                        if ($this->getErrors()) {
                            return false;
                        }
                    }

                    if ($values['password'] != $values['password_confirm']) {
                        $this->addError(__('Passwords are different', 'salon-booking-system'));
                        if ($this->getErrors()) {
                            return false;
                        }
                    }

                    if(!$this->getShortcode()->needSms()) {
                        if ($this->successRegistration($values) === false) {
			                return false;
			            }
                    }else{
			            $_SESSION['sln_detail_step_need_register_user'] = true;
                        $_SESSION['sln_detail_step'] = $values;
                    }
                }
            }else{
                $update = [
                    'ID' => $current_user->ID,
                ];
                if(isset($values['firstname'])){
                    $update['first_name'] = $values['firstname'];
                }
                if(isset($values['lastname'])){
                    $update['last_name'] = $values['lastname'];
                }
                wp_update_user( $update );

                $user_meta_fields = SLN_Enum_CheckoutFields::forRegistration()->appendSmsPrefix()->keys();
                foreach($user_meta_fields as $k){
                    if(in_array($k,['firstname','lastname', 'sms_prefix'])) continue;
                    if (SLN_Enum_CheckoutFields::getField($k) && SLN_Enum_CheckoutFields::getField($k)->get('type') === 'file' && isset($values[$k]) && is_array($values[$k])) {
                        $data = array_map(function($file) {
                            return array(
                                'subdir' => wp_upload_dir()['subdir'],
                                'file'   => basename((string) $file),
                            );
                        }, $values[$k]);
                        update_user_meta($current_user->ID, '_sln_'.$k, $data);
                    } else {
                        if(isset($values[$k])){
                           update_user_meta($current_user->ID, '_sln_'.$k, $values[$k]);
                        }
                    }
                }
		        do_action('sln.shortcode.details.dispatchForm.logged_checkout', $values, $this);
            }
        }

	if ( empty( $values ) ) {
	    return false;
	}

	if ( ! apply_filters('sln.shortcode.details.dispatchForm.validate_bind_values', true, $values, $this) ) {
	    return false;
	}

        $this->bindValues($values);

        return true;
    }

    private function dispatchAuthFB($accessToken) {

	try {

	    $userID = SLN_Helper_FacebookLogin::getUserIDByAccessToken($accessToken, true);

	    $user = get_user_by('id', $userID);

	    wp_set_auth_cookie($userID);
	    wp_set_current_user($userID);

	    $tmp = explode(' ', $user->display_name);

	    $tmp_lastname  = array_pop($tmp);
	    $tmp_firstname = implode(' ', $tmp);

	    $firstname = $user->user_firstname ? $user->user_firstname : $tmp_firstname;
	    $lastname  = $user->user_lastname ? $user->user_lastname : $tmp_lastname;

	    return array(
		'fb_id'     => get_user_meta($userID, '_sln_fb_id', true),
		'firstname' => $firstname,
		'lastname'  => $lastname,
		'email'     => $user->user_email,
		'phone'     => get_user_meta($userID, '_sln_phone', true),
		'address'   => '',
	    );

	} catch (\Exception $ex) {
	    $this->addError($ex->getMessage());
	}

	return array();
    }

    private function validate($values){
        $fields = SLN_Enum_CheckoutFields::forDetailsStep();

        foreach ($fields as $key => $field) {
            if ($field->isRequiredNotHidden() && empty($values[$key])){
                $this->addError(esc_html__($field['label'].' can\'t be empty', 'salon-booking-system'));
            }
        }

        $email = SLN_Enum_CheckoutFields::getField('email');
        if ($email->isRequired() && !filter_var($values['email'], FILTER_VALIDATE_EMAIL)) {
                $this->addError(__('e-mail is not valid', 'salon-booking-system'));
            }
        }

    public function render()
    {
        $bb = $this->getPlugin()->getBookingBuilder();
        $custom_url = apply_filters('sln.shortcode.details.render.custom_url', false, $this, $bb);
        if ($custom_url) {
            $this->redirect($custom_url);
        } else {
            return parent::render();
        }
    }

    public function redirect($url)
    {
        if ($this->isAjax()) {
            throw new SLN_Action_Ajax_RedirectException($url);
        } else {
            wp_redirect($url);
        }
    }

    protected function isAjax()
    {
        return defined('DOING_AJAX') && DOING_AJAX;
    }

    public function getTitleKey(){
        if(!is_user_logged_in() && !isset($this->getPlugin()->getSEttings()->get('custom_texts')['Checkout'])){
            if($this->getPlugin()->getSettings()->get('enabled_force_guest_checkout')){
                return 'Fill out the form to complete the booking';
            }
            return 'Returning customer?';
        }
        return 'Checkout';
    }

    public function getTitleLabel(){
        if(!is_user_logged_in()){
            if($this->getPlugin()->getSettings()->get('enabled_force_guest_checkout')){
                return __('Fill out the form to complete the booking', 'salon-booking-system');
            }
            return __('Returning customer?', 'salon-booking-system');
        }
        return __('Checkout', 'salon-booking-system');
    }
}
