<?php
/**
 * Google Sheets Product Sync Manager
 *
 * @package ShopExplorer\GoogleSheets
 * @since 1.0.0
 */

namespace SHOPEXPLORER\GoogleSheets;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Product Sync Manager class
 *
 * Handles syncing WooCommerce products to Google Sheets
 *
 * @since 1.0.0
 */
class SHOPEX_ProductSyncManager {

	/**
	 * Service Account Auth instance
	 *
	 * @var ServiceAccountAuth
	 */
	private $auth_manager;

	/**
	 * Constructor
	 */
	public function __construct() {
		$this->auth_manager = new SHOPEX_ServiceAccountAuth();
	}

	/**
	 * Get available product fields for syncing
	 *
	 * @return array
	 */
	public function get_available_fields() {
		$fields = [
			'product_id' => [
				'label' => 'Product ID',
				'type' => 'core',
				'enabled' => true, // Always enabled
			],
			'product_name' => [
				'label' => 'Product Name',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_product_name', true ),
			],
			'sku' => [
				'label' => 'SKU',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_sku', true ),
			],
			'regular_price' => [
				'label' => 'Regular Price',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_regular_price', true ),
			],
			'sale_price' => [
				'label' => 'Sale Price',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_sale_price', false ),
			],
			'stock_quantity' => [
				'label' => 'Stock Quantity',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_stock_quantity', true ),
			],
			'stock_status' => [
				'label' => 'Stock Status',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_stock_status', true ),
			],
			'product_type' => [
				'label' => 'Product Type',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_product_type', false ),
			],
			'categories' => [
				'label' => 'Categories',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_categories', false ),
			],
			'weight' => [
				'label' => 'Weight',
				'type' => 'core',
				'enabled' => (bool) get_option( 'shopex_sync_weight', false ),
			],
		];

		return $fields;
	}

	/**
	 * Get current field settings
	 *
	 * @return array
	 */
	public function get_field_settings() {
		try {
			return $this->get_available_fields();
		} catch ( \Exception $e ) {
			error_log( 'Error getting product sync fields: ' . $e->getMessage() );
			return [];
		}
	}

	/**
	 * Update field settings
	 *
	 * @param array $field_settings Field settings
	 * @return bool
	 */
	public function update_field_settings( $field_settings ) {
		$available_fields = $this->get_available_fields();

		foreach ( $field_settings as $field_key => $enabled ) {
			if ( isset( $available_fields[ $field_key ] ) && $field_key !== 'product_id' ) {
				update_option( 'shopex_sync_' . $field_key, (bool) $enabled );
			}
		}

		return true;
	}

	/**
	 * Get enabled fields only
	 *
	 * @return array
	 */
	public function get_enabled_fields() {
		$fields = $this->get_available_fields();
		return array_filter( $fields, function ( $field ) {
			return $field['enabled'];
		});
	}

	/**
	 * Get column headers for Google Sheets
	 *
	 * @return array
	 */
	public function get_column_headers() {
		$enabled_fields = $this->get_enabled_fields();
		return array_column( $enabled_fields, 'label' );
	}

	/**
	 * Get all products data for syncing
	 *
	 * @param array $args Query arguments
	 * @return array
	 */
	public function get_products_data( $args = [] ) {
		$default_args = [
			'limit' => -1,
			'status' => 'any',
			'return' => 'objects',
		];

		$args = wp_parse_args( $args, $default_args );

		if ( ! function_exists( 'wc_get_products' ) ) {
			return [];
		}

		$products = wc_get_products( $args );
		$products_data = [];

		foreach ( $products as $product ) {
			$products_data[] = $this->format_product_data( $product );
		}

		return $products_data;
	}

	/**
	 * Format single product data
	 *
	 * @param \WC_Product $product WooCommerce product object
	 * @return array
	 */
	public function format_product_data( $product ) {
		$enabled_fields = $this->get_enabled_fields();
		$product_data = [];

		foreach ( array_keys( $enabled_fields ) as $field_key ) {
			switch ( $field_key ) {
				case 'product_id':
					$product_data[] = $product->get_id();
					break;

				case 'product_name':
					$product_data[] = $product->get_name();
					break;

				case 'sku':
					$product_data[] = $product->get_sku();
					break;

				case 'regular_price':
					$product_data[] = $product->get_regular_price();
					break;

				case 'sale_price':
					$product_data[] = $product->get_sale_price();
					break;

				case 'stock_quantity':
					$product_data[] = $product->get_stock_quantity();
					break;

				case 'stock_status':
					$product_data[] = ucfirst( $product->get_stock_status() );
					break;

				case 'product_type':
					$product_data[] = ucfirst( $product->get_type() );
					break;

				case 'categories':
					$categories = wp_get_post_terms( $product->get_id(), 'product_cat', [ 'fields' => 'names' ] );
					$product_data[] = is_array( $categories ) ? implode( ', ', $categories ) : '';
					break;

				case 'weight':
					$product_data[] = $product->get_weight();
					break;

				default:
					$product_data[] = '';
					break;
			}
		}

		return $product_data;
	}

	/**
	 * Sync all products to Google Sheets
	 *
	 * @param string $spreadsheet_id Google Sheets spreadsheet ID
	 * @param string $sheet_name Sheet name/tab
	 * @return array Result with success status and message
	 */
	public function sync_all_products( $spreadsheet_id, $sheet_name = 'Products' ) {
		try {
			if ( ! $this->auth_manager->has_credentials() ) {
				error_log( 'ProductSync: No credentials configured' );
				return [
					'success' => false,
					'message' => __( 'Google Sheets credentials not configured. Please configure your service account credentials.', 'shop-explorer' ),
				];
			}

			// Get access token
			$access_token = $this->auth_manager->get_access_token();
			if ( ! $access_token ) {
				error_log( 'ProductSync: Failed to get access token' );
				return [
					'success' => false,
					'message' => __( 'Failed to get access token. Please check your credentials.', 'shop-explorer' ),
				];
			}

			// Get products data
			$products_data = $this->get_products_data();
			if ( empty( $products_data ) ) {
				return [
					'success' => false,
					'message' => __( 'No products found to sync.', 'shop-explorer' ),
				];
			}

			// Prepare data with headers
			$headers = $this->get_column_headers();
			$sheet_data = array_merge( [ $headers ], $products_data );

			// Clear existing data and add new data
			$this->clear_sheet( $access_token, $spreadsheet_id, $sheet_name );
			$result = $this->write_to_sheet( $access_token, $spreadsheet_id, $sheet_name, $sheet_data );

			if ( $result ) {
				return [
					'success' => true,
					/* translators: %s: is the product count */
					'message' => sprintf( __( 'Successfully synced %d products to Google Sheets.', 'shop-explorer' ), count( $products_data ) ),
					'synced_count' => count( $products_data ),
				];
			} else {
				return [
					'success' => false,
					'message' => __( 'Failed to write data to Google Sheets. Please check spreadsheet permissions.', 'shop-explorer' ),
				];
			}
		} catch ( \Exception $e ) {
			return [
				'success' => false,
				'message' => __( 'Failed to sync products: ', 'shop-explorer' ) . $e->getMessage(),
			];
		}
	}

	/**
	 * Clear sheet data
	 *
	 * @param string $access_token Access token
	 * @param string $spreadsheet_id Spreadsheet ID
	 * @param string $sheet_name Sheet name
	 * @return bool
	 */
	private function clear_sheet( $access_token, $spreadsheet_id, $sheet_name ) {
		$api_url = "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheet_id}/values/{$sheet_name}:clear";

		$response = \wp_remote_post( $api_url, [
			'headers' => [
				'Authorization' => 'Bearer ' . $access_token,
				'Content-Type' => 'application/json',
			],
			'timeout' => 30,
		] );

		return ! \is_wp_error( $response ) && \wp_remote_retrieve_response_code( $response ) === 200;
	}

	/**
	 * Write data to sheet
	 *
	 * @param string $access_token Access token
	 * @param string $spreadsheet_id Spreadsheet ID
	 * @param string $sheet_name Sheet name
	 * @param array  $data Data to write
	 * @return bool
	 */
	private function write_to_sheet( $access_token, $spreadsheet_id, $sheet_name, $data ) {
		$api_url = "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheet_id}/values/{$sheet_name}?valueInputOption=USER_ENTERED";

		$response = \wp_remote_request( $api_url, [
			'method' => 'PUT',
			'headers' => [
				'Authorization' => 'Bearer ' . $access_token,
				'Content-Type' => 'application/json',
			],
			'body' => \json_encode( [
				'values' => $data,
			] ),
			'timeout' => 30,
		] );

		return ! \is_wp_error( $response ) && \wp_remote_retrieve_response_code( $response ) === 200;
	}

	/**
	 * Sync single product to Google Sheets
	 *
	 * @param int    $product_id Product ID
	 * @param string $spreadsheet_id Google Sheets spreadsheet ID
	 * @param string $sheet_name Sheet name/tab
	 * @return array Result with success status and message
	 */
	public function sync_single_product( $product_id, $spreadsheet_id, $sheet_name = 'Products' ) {
		try {
			$product = wc_get_product( $product_id );
			if ( ! $product ) {
				return [
					'success' => false,
					'message' => __( 'Product not found.', 'shop-explorer' ),
				];
			}

			if ( ! $this->auth_manager->has_credentials() ) {
				return [
					'success' => false,
					'message' => __( 'Google Sheets credentials not configured.', 'shop-explorer' ),
				];
			}

			$access_token = $this->auth_manager->get_access_token();
			if ( ! $access_token ) {
				return [
					'success' => false,
					'message' => __( 'Failed to get access token.', 'shop-explorer' ),
				];
			}

			// Format product data
			$product_data = $this->format_product_data( $product );

			// Find existing row or append new one
			$existing_data = $this->get_sheet_data( $access_token, $spreadsheet_id, $sheet_name );
			$row_index = $this->find_product_row( $existing_data, $product_id );

			if ( $row_index !== null ) {
				// Update existing row
				$result = $this->update_sheet_row( $access_token, $spreadsheet_id, $sheet_name, $row_index, $product_data );
			} else {
				// Append new row
				$result = $this->append_to_sheet( $access_token, $spreadsheet_id, $sheet_name, [ $product_data ] );
			}

			if ( $result ) {
				return [
					'success' => true,
					/* translators: %s: is the product id */
					'message' => sprintf( __( 'Successfully synced product #%d to Google Sheets.', 'shop-explorer' ), $product_id ),
				];
			} else {
				return [
					'success' => false,
					'message' => __( 'Failed to sync product.', 'shop-explorer' ),
				];
			}
		} catch ( \Exception $e ) {
			return [
				'success' => false,
				'message' => __( 'Failed to sync product.', 'shop-explorer' ),
			];
		}
	}

	/**
	 * Append data to sheet
	 *
	 * @param string $access_token Access token
	 * @param string $spreadsheet_id Spreadsheet ID
	 * @param string $sheet_name Sheet name
	 * @param array  $data Data to append
	 * @return bool
	 */
	private function append_to_sheet( $access_token, $spreadsheet_id, $sheet_name, $data ) {
		$api_url = "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheet_id}/values/{$sheet_name}:append?valueInputOption=USER_ENTERED";

		$response = \wp_remote_post( $api_url, [
			'headers' => [
				'Authorization' => 'Bearer ' . $access_token,
				'Content-Type' => 'application/json',
			],
			'body' => \json_encode( [
				'values' => $data,
			] ),
			'timeout' => 30,
		] );

		return ! \is_wp_error( $response ) && \wp_remote_retrieve_response_code( $response ) === 200;
	}

	/**
	 * Get sheet data
	 *
	 * @param string $access_token Access token
	 * @param string $spreadsheet_id Spreadsheet ID
	 * @param string $sheet_name Sheet name
	 * @return array|null
	 */
	private function get_sheet_data( $access_token, $spreadsheet_id, $sheet_name ) {
		$api_url = "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheet_id}/values/{$sheet_name}";

		$response = \wp_remote_get( $api_url, [
			'headers' => [
				'Authorization' => 'Bearer ' . $access_token,
			],
			'timeout' => 30,
		] );

		if ( \is_wp_error( $response ) || \wp_remote_retrieve_response_code( $response ) !== 200 ) {
			return null;
		}

		$body = \wp_remote_retrieve_body( $response );
		$data = \json_decode( $body, true );

		return isset( $data['values'] ) ? $data['values'] : null;
	}

	/**
	 * Find product row in sheet data
	 *
	 * @param array $sheet_data Sheet data
	 * @param int   $product_id Product ID to find
	 * @return int|null Row index (1-based) or null if not found
	 */
	private function find_product_row( $sheet_data, $product_id ) {
		if ( ! $sheet_data ) {
			return null;
		}

		foreach ( $sheet_data as $index => $row ) {
			if ( isset( $row[0] ) && $row[0] === $product_id ) {
				return $index + 1; // Google Sheets uses 1-based indexing
			}
		}

		return null;
	}

	/**
	 * Update specific row in sheet
	 *
	 * @param string $access_token Access token
	 * @param string $spreadsheet_id Spreadsheet ID
	 * @param string $sheet_name Sheet name
	 * @param int    $row_index Row index (1-based)
	 * @param array  $data Row data
	 * @return bool
	 */
	private function update_sheet_row( $access_token, $spreadsheet_id, $sheet_name, $row_index, $data ) {
		$range = "{$sheet_name}!A{$row_index}";
		$api_url = "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheet_id}/values/{$range}?valueInputOption=USER_ENTERED";

		$response = \wp_remote_request( $api_url, [
			'method' => 'PUT',
			'headers' => [
				'Authorization' => 'Bearer ' . $access_token,
				'Content-Type' => 'application/json',
			],
			'body' => \json_encode( [
				'values' => [ $data ],
			] ),
			'timeout' => 30,
		] );

		return ! \is_wp_error( $response ) && \wp_remote_retrieve_response_code( $response ) === 200;
	}
}
