<?php
namespace Wpcafe_Multivendor\Core\Settings;

defined( "ABSPATH" ) || exit;

use WpCafe\Abstract\Base_Rest_Controller;
use WP_REST_Server;
use WP_REST_Request;

/**
 * Settings Controller for managing vendor-specific WPCafe settings.
 */
class Settings_Controller extends Base_Rest_Controller {

	use \Wpcafe_Multivendor\Traits\Singleton;

	/**
	 * Endpoint namespace
	 *
	 * @var string
	 */
	protected $namespace = 'wpcafe-multivendor/v1';

	/**
	 * Route base
	 *
	 * @var string
	 */
	protected $rest_base = 'settings';

	/**
	 * The user meta key where vendor settings are stored
	 */
	const SETTINGS_META_KEY = 'dokan_wpcafe_settings';

	/**
	 * Default settings structure
	 */
	private $default_settings = [
		'allow_vendor_food_location' => false,
		'storefront_template' => 'default',
		'delivery_location' => [],
	];

	/**
	 * Register REST API routes
	 *
	 * @return void
	 */
	public function register_routes() {
		// Get/Update settings for current vendor
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base,
			[
				[
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => [ $this, 'get_vendor_settings' ],
					'permission_callback' => [ $this, 'get_vendor_settings_permission_check' ],
				],
				[
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => [ $this, 'update_vendor_settings' ],
					'permission_callback' => [ $this, 'update_vendor_settings_permission_check' ],
				],
			]
		);
	}

	/**
	 * REST API: Get settings for current vendor
	 *
	 * @param WP_REST_Request $request Full request data
	 * @return \WP_HTTP_Response
	 */
	public function get_vendor_settings( $request ) {
		$settings = $this->get_settings();

		return $this->response( $settings, 200, __( 'Settings retrieved successfully', 'wpcafe-multivendor' ) );
	}

	/**
	 * REST API: Update settings for current vendor
	 *
	 * @param WP_REST_Request $request Full request data
	 * @return \WP_HTTP_Response
	 */
	public function update_vendor_settings( $request ) {
		$body = $request->get_body();
		$params = json_decode( $body, true );

		$success = $this->update_settings( $params );

		if ( ! $success ) {
			return $this->error( __( 'Failed to update settings', 'wpcafe-multivendor' ), 500 );
		}

		$settings = $this->get_settings();
		return $this->response( $settings, 200, __( 'Settings updated successfully', 'wpcafe-multivendor' ) );
	}

	/**
	 * Permission check for getting settings
	 *
	 * @param WP_REST_Request $request Full request data
	 * @return bool
	 */
	public function get_vendor_settings_permission_check( $request ) {
		return $this->check_vendor_permission();
	}

	/**
	 * Permission check for updating settings
	 *
	 * @param WP_REST_Request $request Full request data
	 * @return bool
	 */
	public function update_vendor_settings_permission_check( $request ) {
		return $this->check_vendor_permission();
	}

	/**
	 * Validate vendor permissions for current user
	 *
	 * @return bool True if current user is a vendor or admin
	 */
	protected function check_vendor_permission() {
		$current_user_id = get_current_user_id();

		if ( ! $current_user_id ) {
			return false;
		}

		if ( current_user_can( 'manage_options' ) ) {
			return true;
		}

		if ( function_exists( 'dokan_is_user_seller' ) ) {
			return dokan_is_user_seller( $current_user_id );
		}

		return false;
	}

	/**
	 * Get all settings for a specific vendor
	 *
	 * @param int|null $vendor_id The vendor user ID. If null, uses current user.
	 * @return array The vendor settings array
	 */
	public function get_settings( $vendor_id = null ) {
		$vendor_id = $this->get_vendor_id( $vendor_id );

		if ( ! $vendor_id ) {
			return $this->default_settings;
		}

		$settings = get_user_meta( $vendor_id, self::SETTINGS_META_KEY, true );

		// Merge with defaults to ensure all keys exist
		if ( ! is_array( $settings ) ) {
			$settings = [];
		}

		return wp_parse_args( $settings, $this->default_settings );
	}

	/**
	 * Update all settings for a specific vendor
	 *
	 * @param array $settings The settings array to save
	 * @param int|null $vendor_id The vendor user ID. If null, uses current user.
	 * @return bool True on success, false on failure
	 */
	public function update_settings( $settings, $vendor_id = null ) {
		$vendor_id = $this->get_vendor_id( $vendor_id );

		if ( ! $vendor_id ) {
			return false;
		}

		// Sanitize settings before saving
		$sanitized_settings = $this->sanitize_settings( $settings );

		try {
			update_user_meta( $vendor_id, self::SETTINGS_META_KEY, $sanitized_settings );
		} catch (\Throwable $e) {
			return false;
		}
		
		return true;
	}

	/**
	 * Get the vendor ID, using current user if not provided
	 *
	 * @param int|null $vendor_id The vendor user ID
	 * @return int|false The vendor ID or false if invalid
	 */
	private function get_vendor_id( $vendor_id = null ) {
		if ( $vendor_id === null ) {
			if ( function_exists( 'dokan_get_current_user_id' ) ) {
				$vendor_id = dokan_get_current_user_id();
			} else {
				$vendor_id = get_current_user_id();
			}
		}

		// Validate vendor ID
		if ( ! $vendor_id || ! is_numeric( $vendor_id ) ) {
			return false;
		}

		return absint( $vendor_id );
	}

	/**
	 * Sanitize settings array before saving
	 *
	 * @param array $settings The settings array to sanitize
	 * @return array The sanitized settings
	 */
	private function sanitize_settings( $settings ) {
		$sanitized = [];

		// Sanitize each setting based on its type
		foreach ( $settings as $key => $value ) {
			switch ( $key ) {
				case 'delivery_location':
					// Array field
					$sanitized[ $key ] = is_array( $value ) ? array_map( 'sanitize_text_field', $value ) : [];
					break;

				case 'storefront_template':
					// Template field with default
					$sanitized[ $key ] = ! empty( $value ) ? sanitize_text_field( $value ) : 'default';
					break;

				case 'allow_vendor_food_location':
					// Checkbox field
					$sanitized[ $key ] = ! empty( $value ) ? sanitize_text_field( $value ) : '';
					break;

				default:
					// Unknown field - sanitize as text
					$sanitized[ $key ] = ! empty( $value ) ? sanitize_text_field( $value ) : '';
					break;
			}
		}

		return $sanitized;
	}
}
