<?php
/**
 * API operations - fetch data from STW platform using JWT
 *
 * @package Scanshow
 */

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

// Load environment configuration
require_once plugin_dir_path( __FILE__ ) . 'env.php';

class Scan_Show_API {
	/**
	 * Get backend API URL from environment configuration
	 */
	public static function get_backend_url() {
		return Scan_Show_Env::BACKEND_URL;
	}

	/**
	 * Get frontend URL from environment configuration
	 */
	public static function get_frontend_url() {
		return Scan_Show_Env::FRONTEND_URL;
	}

	public static function login( $email, $password ) {
		// Get WordPress site domain
		$domain = get_site_url();
		
		$url = self::get_backend_url() . 'v1/auth/connect/wordpress';
		
		$response = wp_remote_post( $url, array(
			'headers'     => array( 'Content-Type' => 'application/json' ),
			'body'        => wp_json_encode( array(
				'email'    => $email,
				'password' => $password,
				'domain'   => $domain,
			) ),
			'timeout'     => 30,
			'sslverify'   => true,
		) );
		
		// Handle network errors
		if ( is_wp_error( $response ) ) {
			return array(
				'success' => false,
				'message' => 'Connection error: ' . $response->get_error_message(),
			);
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );
		
		// Handle shop already connected error (409 Conflict)
		if ( $status_code === 409 && isset( $data['code'] ) && $data['code'] === 'SHOP_ALREADY_CONNECTED' ) {
			return array(
				'success'       => false,
				'code'          => 'SHOP_ALREADY_CONNECTED',
				'message'       => $data['error'] ?? 'Account already connected to another shop',
				'existing_shop' => $data['existing_shop'] ?? null,
			);
		}
		
		// Handle API errors
		if ( $status_code !== 200 ) {
			$error_msg = isset( $data['error'] ) ? $data['error'] : 'Invalid credentials';
			return array(
				'success' => false,
				'message' => $error_msg,
			);
		}
		
		// Extract data from response
		if ( ! isset( $data['data'] ) ) {
			return array(
				'success' => false,
				'message' => 'Invalid API response format',
			);
		}
		
		$api_data = $data['data'];
		$token    = $api_data['token'] ?? null;
		$shop_id  = $api_data['shop_id'] ?? null;
		
		if ( ! $token || ! $shop_id ) {
			return array(
				'success' => false,
				'message' => 'Invalid API response: missing token or shop_id',
			);
		}
		
		// Save non-expiring JWT token and shop_id to database
		Scan_Show_Database::save_jwt( $token, $shop_id );
		
		return array(
			'success' => true,
			'data'    => array(
				'token'   => $token,
				'shop_id' => $shop_id,
			),
		);
	}

	public static function is_connected() {
		$jwt = Scan_Show_Database::get_jwt();
		return ! empty( $jwt );
	}

	public static function get_user_data() {
		$jwt = Scan_Show_Database::get_jwt();
		if ( ! $jwt ) {
			return array( 'error' => 'Not connected' );
		}

		$url = self::get_backend_url() . 'v1/user';
		
		$response = wp_remote_get( $url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );
		
		if ( $status_code !== 200 ) {
			return array( 'error' => isset( $data['error'] ) ? $data['error'] : 'Failed to fetch user data' );
		}
		
		return isset( $data['data']['user'] ) ? $data['data']['user'] : array( 'error' => 'Invalid response format' );
	}

	public static function get_connection_status() {
		$jwt = Scan_Show_Database::get_jwt();
		if ( ! $jwt ) {
			return array(
				'connected' => false,
				'message'   => 'Not connected to STW Platform',
			);
		}

		$user_data = self::get_user_data();
		
		if ( isset( $user_data['error'] ) ) {
			return array(
				'connected' => false,
				'message'   => $user_data['error'],
			);
		}

		return array(
			'connected'  => true,
			'user_email' => isset( $user_data['email_address'] ) ? $user_data['email_address'] : '',
			'username'   => isset( $user_data['username'] ) ? $user_data['username'] : '',
		);
	}

	public static function get_subscription() {
		$jwt = Scan_Show_Database::get_jwt();
		if ( ! $jwt ) {
			return array( 'error' => 'Not connected' );
		}

		$url = self::get_backend_url() . 'v1/user/subscription';
		
		$response = wp_remote_get( $url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );
		
		if ( $status_code !== 200 ) {
			return array( 'error' => isset( $data['error'] ) ? $data['error'] : 'Failed to fetch subscription data' );
		}
		
		return isset( $data['data']['subscription'] ) ? $data['data']['subscription'] : array( 'error' => 'Invalid response format' );
	}

	public static function get_quota() {
		$jwt = Scan_Show_Database::get_jwt();
		if ( ! $jwt ) {
			return array( 'error' => 'Not connected' );
		}

		// Fetch quota data
		$quota_url = self::get_backend_url() . 'v1/user/quotas';
		$quota_response = wp_remote_get( $quota_url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $quota_response ) ) {
			return array( 'error' => 'Connection error: ' . $quota_response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $quota_response );
		$body        = wp_remote_retrieve_body( $quota_response );
		$quota_data  = json_decode( $body, true );
		
		if ( $status_code !== 200 ) {
			return array( 'error' => isset( $quota_data['error'] ) ? $quota_data['error'] : 'Failed to fetch quota data' );
		}
		
		$quotas = isset( $quota_data['data']['quotas'] ) ? $quota_data['data']['quotas'] : array();
		
		// Fetch subscription data
		$subscription = self::get_subscription();
		
		// Fetch user data
		$user = self::get_user_data();
		
		// Combine all data
		return array(
			'quotas'       => $quotas,
			'subscription' => $subscription,
			'user'         => $user,
		);
	}

	public static function get_woocommerce_products() {
		if ( ! class_exists( 'WooCommerce' ) ) {
			return array( 'error' => 'WooCommerce is not active' );
		}

		$query = new WC_Product_Query( array(
			'limit'  => -1,
			'status' => array( 'publish', 'draft', 'private' ),
		) );
		$products = array();

		foreach ( $query->get_products() as $product ) {
			$thumbnail_id = $product->get_image_id();
			$image_url = $thumbnail_id ? wp_get_attachment_image_url( $thumbnail_id, 'thumbnail' ) : '';
			
			// Get product categories
			$category_ids = $product->get_category_ids();
			$categories = array();
			foreach ( $category_ids as $cat_id ) {
				$term = get_term( $cat_id, 'product_cat' );
				if ( $term && ! is_wp_error( $term ) ) {
					$categories[] = array(
						'id'   => $term->term_id,
						'name' => $term->name,
						'slug' => $term->slug,
					);
				}
			}

			$products[] = array(
				'id'         => $product->get_id(),
				'name'       => $product->get_name(),
				'price'      => $product->get_price(),
				'status'     => get_post_status( $product->get_id() ),
				'image'      => $image_url,
				'categories' => $categories,
			);
		}
		return $products;
	}

	public static function get_woocommerce_categories() {
		if ( ! class_exists( 'WooCommerce' ) ) {
			return array( 'error' => 'WooCommerce is not active' );
		}

		$terms = get_terms( array(
			'taxonomy'   => 'product_cat',
			'hide_empty' => false,
		) );

		if ( is_wp_error( $terms ) ) {
			return array( 'error' => $terms->get_error_message() );
		}

		$categories = array();
		foreach ( $terms as $term ) {
			$categories[] = array(
				'id'    => $term->term_id,
				'name'  => $term->name,
				'slug'  => $term->slug,
				'count' => $term->count,
			);
		}

		return $categories;
	}

	/**
	 * Get linked items from backend API
	 * GET /v1/wordpress/:shopId/items
	 */
	public static function get_linked_items() {
		$jwt = Scan_Show_Database::get_jwt();
		$shop_id = Scan_Show_Database::get_shop_id();
		
		if ( ! $jwt || ! $shop_id ) {
			return array( 'error' => 'Not connected' );
		}

		$url = self::get_backend_url() . 'v1/wordpress/' . $shop_id . '/items';
		
		$response = wp_remote_get( $url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );
		
		if ( $status_code !== 200 ) {
			return array( 'error' => isset( $data['error'] ) ? $data['error'] : 'Failed to fetch linked items' );
		}
		
		return isset( $data['items'] ) ? $data['items'] : array();
	}

	/**
	 * Check if a product is linked to an STW item
	 * GET /v1/wordpress/item/:shopId/:productId
	 * 
	 * @param string $product_id WordPress product ID
	 * @return array|false Returns item data if linked, false if not linked or error
	 */
	public static function get_product_item( $product_id ) {
		$jwt = Scan_Show_Database::get_jwt();
		$shop_id = Scan_Show_Database::get_shop_id();
		
		if ( ! $jwt || ! $shop_id ) {
			return false;
		}

		$url = self::get_backend_url() . 'v1/wordpress/item/' . $shop_id . '/' . $product_id;
		
		$response = wp_remote_get( $url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return false;
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		
		// If product is not linked, API returns error status
		if ( $status_code !== 200 ) {
			return false;
		}
		
		$body = wp_remote_retrieve_body( $response );
		$data = json_decode( $body, true );
		
		// Return item data if found
		return isset( $data['data']['item'] ) ? $data['data']['item'] : false;
	}

	/**
	 * Construct iframe URL for 3D viewer
	 * Only returns URL if product is actually linked to an STW item
	 * Format: /item/wordpress/[shopId]/[productId]
	 */
	public static function get_iframe_url( $product_id ) {
		$shop_id = Scan_Show_Database::get_shop_id();
		
		if ( ! $shop_id ) {
			return null;
		}
		
		// Check if product is linked before constructing URL
		$item = self::get_product_item( $product_id );
		
		if ( ! $item ) {
			return null;
		}
		
		$frontend_url = self::get_frontend_url();
		return $frontend_url . 'item/wordpress/' . $shop_id . '/' . $product_id;
	}

	/**
	 * Get iframe URL for a page (not product)
	 * Format: /item/[itemId]/embed or /scene/[roomId]/embed
	 *
	 * @param int $page_id WordPress page/post ID
	 * @return string|null Iframe URL or null if not linked
	 */
	public static function get_page_iframe_url( $page_id ) {
		// Get linked data from database
		$link_data = Scan_Show_Database::get_page_link_data( $page_id );
		
		if ( ! $link_data || ! isset( $link_data['entity_id'] ) ) {
			return null;
		}
		
		// Construct embed URL based on type
		$frontend_url = self::get_frontend_url();
		$type = isset( $link_data['entity_type'] ) ? $link_data['entity_type'] : 'item';
		
		if ( $type === 'room' ) {
			// Rooms use /scene/ path for embed URLs
			return rtrim( $frontend_url, '/' ) . '/scene/' . $link_data['entity_id'] . '/embed';
		} else {
			return rtrim( $frontend_url, '/' ) . '/item/' . $link_data['entity_id'] . '/embed';
		}
	}

	/**
	 * Get rooms from backend API
	 * GET /v1/rooms?userId={userId}&isPublishedOnly=true&page=1&pageSize=100
	 * 
	 * @param int $page Page number (default 1)
	 * @param int $page_size Number of items per page (default 100)
	 * @return array List of rooms or error
	 */
	public static function get_rooms( $page = 1, $page_size = 100 ) {
		$jwt = Scan_Show_Database::get_jwt();
		
		if ( ! $jwt ) {
			return array( 'error' => 'Not connected' );
		}

		// Get user data to retrieve user ID
		$user_data = self::get_user_data();
		
		if ( isset( $user_data['error'] ) || ! isset( $user_data['id'] ) ) {
			return array( 'error' => 'Unable to retrieve user information' );
		}
		
		$user_id = $user_data['id'];
		
		// Construct URL with query parameters - only get published rooms
		$url = self::get_backend_url() . 'v1/rooms?' . http_build_query( array(
			'userId'           => $user_id,
			'isPublishedOnly'  => 'true',
			'page'             => $page,
			'pageSize'         => $page_size,
		) );
		
		$response = wp_remote_get( $url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );
		
		if ( $status_code !== 200 ) {
			return array( 'error' => isset( $data['error'] ) ? $data['error'] : 'Failed to fetch rooms' );
		}
		
		// Return rooms array from data
		return isset( $data['data']['rooms'] ) ? $data['data']['rooms'] : array();
	}

	/**
	 * Enable embed for an item
	 * POST /v1/item/{id}/embed
	 * 
	 * @param string $item_id STW item ID
	 * @return array Success or error response
	 */
	public static function enable_item_embed( $item_id ) {
		$jwt = Scan_Show_Database::get_jwt();
		
		if ( ! $jwt ) {
			return array( 'success' => false, 'error' => 'Not connected' );
		}

		$url = self::get_backend_url() . 'v1/item/' . urlencode( $item_id ) . '/embed';
		
		$response = wp_remote_post( $url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'body'    => wp_json_encode( array() ),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'success' => false, 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );
		
		if ( $status_code !== 200 ) {
			$error_msg = isset( $data['error'] ) ? $data['error'] : 'Failed to enable embed';
			return array( 'success' => false, 'error' => $error_msg, 'quota_exceeded' => $status_code === 403 );
		}
		
		return array( 'success' => true, 'data' => $data );
	}

	/**
	 * Enable embed for a room
	 * POST /v1/room/{id}/embed
	 * 
	 * @param string $room_id STW room ID
	 * @return array Success or error response
	 */
	public static function enable_room_embed( $room_id ) {
		$jwt = Scan_Show_Database::get_jwt();
		
		if ( ! $jwt ) {
			return array( 'success' => false, 'error' => 'Not connected' );
		}

		$url = self::get_backend_url() . 'v1/room/' . urlencode( $room_id ) . '/embed';
		
		$response = wp_remote_post( $url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'body'    => wp_json_encode( array() ),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'success' => false, 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );
		
		if ( $status_code !== 200 ) {
			$error_msg = isset( $data['error'] ) ? $data['error'] : 'Failed to enable embed';
			return array( 'success' => false, 'error' => $error_msg, 'quota_exceeded' => $status_code === 403 );
		}
		
		return array( 'success' => true, 'data' => $data );
	}

	/**
	 * Get all items (not just embed-enabled)
	 * GET /v1/items?userId={userId}&isPublishedOnly=true
	 * 
	 * @return array List of items or error
	 */
	public static function get_all_items() {
		$jwt = Scan_Show_Database::get_jwt();
		
		if ( ! $jwt ) {
			return array( 'error' => 'Not connected' );
		}

		// Get user data to retrieve user ID
		$user_data = self::get_user_data();
		
		if ( isset( $user_data['error'] ) || ! isset( $user_data['id'] ) ) {
			return array( 'error' => 'Unable to retrieve user information' );
		}
		
		$user_id = $user_data['id'];
		
		// Construct URL with query parameters - only get published items
		$url = self::get_backend_url() . 'v1/items?' . http_build_query( array(
			'userId'           => $user_id,
			'isPublishedOnly'  => 'true',
		) );
		
		$response = wp_remote_get( $url, array(
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
				'Content-Type'  => 'application/json',
			),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		$body        = wp_remote_retrieve_body( $response );
		$data        = json_decode( $body, true );
		
		if ( $status_code !== 200 ) {
			return array( 'error' => isset( $data['error'] ) ? $data['error'] : 'Failed to fetch items' );
		}
		
		// Return items array from data
		return isset( $data['data']['items'] ) ? $data['data']['items'] : array();
	}

	/**
	 * Remove shop connection from STW platform
	 * DELETE /v1/wordpress/install
	 * 
	 * @return array Success or error response
	 */
	public static function remove_shop_connection() {
		$jwt = Scan_Show_Database::get_jwt();
		
		if ( ! $jwt ) {
			// If not connected, no need to call API.
			return array( 'success' => true );
		}

		$url = self::get_backend_url() . 'v1/wordpress/install';
		
		$response = wp_remote_request( $url, array(
			'method'  => 'DELETE',
			'headers' => array(
				'Authorization' => 'Bearer ' . $jwt,
			),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'success' => false, 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		
		if ( $status_code !== 200 ) {
			$body = wp_remote_retrieve_body( $response );
			$data = json_decode( $body, true );
			$error_msg = isset( $data['error'] ) ? $data['error'] : 'Failed to uninstall';
			return array( 'success' => false, 'error' => $error_msg );
		}
		
		return array( 'success' => true );
	}

	/**
	 * Submit feedback to STW platform
	 * POST /v1/user/feedback
	 * 
	 * @param string $text Feedback text (max 300 chars)
	 * @return array Success or error response
	 */
	public static function submit_feedback( $text ) {
		$jwt = Scan_Show_Database::get_jwt();
		
		$url = self::get_backend_url() . 'v1/user/feedback';
		
		$headers = array(
			'Content-Type' => 'application/json',
		);
		
		// Include JWT if connected (for user context)
		if ( $jwt ) {
			$headers['Authorization'] = 'Bearer ' . $jwt;
		}
		
		$response = wp_remote_post( $url, array(
			'headers' => $headers,
			'body'    => wp_json_encode( array(
				'source' => 'wordpress',
				'type'   => 'uninstall',
				'text'   => $text,
			) ),
			'timeout' => 30,
		) );
		
		if ( is_wp_error( $response ) ) {
			return array( 'success' => false, 'error' => 'Connection error: ' . $response->get_error_message() );
		}
		
		$status_code = wp_remote_retrieve_response_code( $response );
		
		if ( $status_code !== 200 ) {
			$body = wp_remote_retrieve_body( $response );
			$data = json_decode( $body, true );
			$error_msg = isset( $data['error'] ) ? $data['error'] : 'Failed to submit feedback';
			return array( 'success' => false, 'error' => $error_msg );
		}
		
		return array( 'success' => true );
	}
}
