<?php
/**
 * Costudio_Admin_Sites — manages the "Sites" tab in standalone mode.
 *
 * @package Contentosapp_Studio
 * @since   1.0.0
 */

defined( 'ABSPATH' ) || exit;

class Costudio_Admin_Sites extends Costudio_Admin_Ajax_Base {

	/**
	 * Singleton instance.
	 */
	private static ?self $instance = null;

	/**
	 * Get the singleton instance.
	 */
	public static function get_instance(): self {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Private constructor.
	 */
	private function __construct() {}

	/**
	 * Register AJAX hooks.
	 */
	public function register_hooks(): void {
		$this->register_ajax_actions( array(
			'costudio_save_site',
			'costudio_delete_site',
			'costudio_test_connection',
			'costudio_fetch_site_categories',
		) );
	}

	/**
	 * AJAX: Save site (create or update).
	 */
	public function ajax_costudio_save_site(): void {
		$in = $this->read_request(
			array(
				'name'       => 'text',
				'url'        => 'url',
				'user'       => 'text',
				'password'   => 'text',
				'color'      => 'text',
				'old_key'    => 'key',
				'site_key'   => 'key',
				'categories' => 'text',
			)
		);

		$name     = $in['name'];
		$url      = $in['url'];
		$user     = $in['user'];
		$password = $in['password'];
		$color    = sanitize_hex_color( $in['color'] ) ?: '#3b82f6';
		$key      = $in['old_key'] ?: $in['site_key'];

		// Categories (optional CSV).
		$categories_csv = $in['categories'];
		$categories     = null;
		if ( ! empty( $categories_csv ) ) {
			$parts      = array_filter( array_map( 'trim', explode( ',', $categories_csv ) ) );
			$categories = array_values( array_map( 'sanitize_text_field', $parts ) );
		}

		if ( empty( $name ) ) {
			wp_send_json_error( __( 'Name is required.', 'contentosapp-studio' ) );
		}

		if ( Costudio_WP_Publisher::LOCAL_SITE_KEY !== $key ) {
			if ( empty( $url ) || empty( $user ) ) {
				wp_send_json_error( __( 'URL and User are required for remote sites.', 'contentosapp-studio' ) );
			}
		}

		$repo = costudio_sites();
		if ( ! $repo ) {
			wp_send_json_error( __( 'Sites system unavailable.', 'contentosapp-studio' ) );
		}

		$site_data = array(
			'key'      => $key ?: sanitize_title( $name ),
			'name'     => $name,
			'label'    => $name,
			'color'    => $color,
			'active'   => true,
		);

		if ( Costudio_WP_Publisher::LOCAL_SITE_KEY === $key ) {
			$existing = $repo->get( $key );
			$site_data['url']      = $existing['url'] ?? rtrim( home_url(), '/' );
			$site_data['user']     = '';
			$site_data['password'] = '';
			$site_data['is_local'] = true;
			$site_data['last_connection_status'] = 'success';
			$site_data['last_connection_test']   = time();
		} else {
			$site_data['url']      = rtrim( $url, '/' );
			$site_data['user']     = $user;
			$site_data['password'] = $password;
		}

		if ( empty( $categories ) ) {
			if ( Costudio_WP_Publisher::LOCAL_SITE_KEY === $key ) {
				$local_categories = [];
				$terms = get_terms( [
					'taxonomy'   => 'category',
					'hide_empty' => false,
				] );

				if ( ! is_wp_error( $terms ) && is_array( $terms ) ) {
					foreach ( $terms as $term ) {
						if ( 'Uncategorized' !== $term->name && 'Sem categoria' !== $term->name ) {
							$local_categories[] = html_entity_decode( $term->name, ENT_QUOTES, 'UTF-8' );
						}
					}
					$categories = array_values( array_unique( $local_categories ) );
				}
			} else {
				$url_to_fetch = rtrim( $url, '/' );
				$auth_headers = ( ! empty( $user ) && '' !== $password )
					? array( 'Authorization' => 'Basic ' . base64_encode( "{$user}:{$password}" ) ) // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
					: array();
				
				$remote_categories = array();
				$page = 1;
				$total_pages = 1;
				
				do {
					$endpoint = $url_to_fetch . '/wp-json/wp/v2/categories?' . http_build_query( array(
						'per_page' => 100,
						'page'     => $page,
						'orderby'  => 'name',
						'order'    => 'asc',
					) );

					$response = wp_safe_remote_get( $endpoint, array(
						'timeout' => 20,
						'headers' => $auth_headers,
					) );

					if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
						break;
					}

					$data = json_decode( wp_remote_retrieve_body( $response ), true );
					if ( ! is_array( $data ) ) {
						break;
					}

					foreach ( $data as $cat ) {
						$cat_name = (string) ( $cat['name'] ?? '' );
						if ( ! empty( $cat_name ) && 'Uncategorized' !== $cat_name && 'Sem categoria' !== $cat_name ) {
							$remote_categories[] = html_entity_decode( $cat_name, ENT_QUOTES, 'UTF-8' );
						}
					}

					$total_pages = (int) wp_remote_retrieve_header( $response, 'X-WP-TotalPages' );
					$page++;
				} while ( $page <= $total_pages && $page <= 5 );
				
				if ( ! empty( $remote_categories ) ) {
					$categories = array_values( array_unique( $remote_categories ) );
				}
			}
		}

		if ( null !== $categories ) {
			$site_data['categories'] = $categories;
		}

		$ok = $repo->save( $site_data );

		// save() returns true on success or a string error message on failure.
		if ( $ok !== true ) {
			$error_msg = is_string( $ok ) && ! empty( $ok )
				? $ok
				: __( 'Could not save the site. Check if it already exists.', 'contentosapp-studio' );
			wp_send_json_error( $error_msg );
		}

		$saved_key = $site_data['key'];
		
		// Auto-test connection after every save so the status is always fresh.
		$test_result = $repo->test_connection( $saved_key );

		wp_send_json_success( array(
			'site'           => $repo->get( $saved_key ),
			'connection_ok'  => $test_result['success'],
			'connection_msg' => $test_result['message'],
		) );
	}

	/**
	 * AJAX: Delete site.
	 */
	public function ajax_costudio_delete_site(): void {
		$in   = $this->read_request( array( 'site_key' => 'key' ) );
		$key  = $in['site_key'];
		$repo = costudio_sites();

		if ( ! $repo ) {
			wp_send_json_error( __( 'Sites system unavailable.', 'contentosapp-studio' ) );
		}

		$repo->delete( $key );
		wp_send_json_success();
	}

	/**
	 * AJAX: Test connection.
	 */
	public function ajax_costudio_test_connection(): void {
		$in = $this->read_request(
			array(
				'site_key' => 'key',
				'url'      => 'url',
				'user'     => 'text',
				'password' => 'text',
			)
		);

		$key = $in['site_key'];
		
		if ( Costudio_WP_Publisher::LOCAL_SITE_KEY === $key ) {
			wp_send_json_success( array(
				'success' => true,
				'message' => __( 'Connected', 'contentosapp-studio' ),
			) );
		}

		$repo = costudio_sites();

		if ( ! $repo ) {
			wp_send_json_error( __( 'Sites system unavailable.', 'contentosapp-studio' ) );
		}

		if ( $key ) {
			$result = $repo->test_connection( $key );
		} else {
			// Test with direct data from form.
			$url      = $in['url'];
			$user     = $in['user'];
			$password = $in['password'];

			// Mock a temporary site config to test.
			$temp_key = 'temp_test_' . time();
			$repo->save( array(
				'key'      => $temp_key,
				'url'      => $url,
				'user'     => $user,
				'password' => $password,
			) );
			$result = $repo->test_connection( $temp_key );
			$repo->delete( $temp_key );
		}

		if ( $result['success'] ) {
			wp_send_json_success( $result );
		} else {
			wp_send_json_error( $result['message'] );
		}
	}

	/**
	 * AJAX: Fetch categories from remote WordPress site.
	 *
	 * Fetches up to 5 pages × 100 categories via the WP REST API,
	 * skipping "Uncategorized", and optionally persists them on a saved site.
	 *
	 * Expects POST params: site_key (optional), url, user, password.
	 *
	 * @since 1.1.0
	 */
	public function ajax_costudio_fetch_site_categories(): void {
		$in = $this->read_request(
			array(
				'site_key' => 'key',
				'url'      => 'url',
				'user'     => 'text',
				'password' => 'text',
			)
		);

		$site_key = $in['site_key'];
		
		if ( Costudio_WP_Publisher::LOCAL_SITE_KEY === $site_key ) {
			$local_categories = [];
			$terms = get_terms( [
				'taxonomy'   => 'category',
				'hide_empty' => false,
			] );

			if ( ! is_wp_error( $terms ) && is_array( $terms ) ) {
				foreach ( $terms as $term ) {
					if ( 'Uncategorized' !== $term->name && 'Sem categoria' !== $term->name ) {
						$local_categories[] = html_entity_decode( $term->name, ENT_QUOTES, 'UTF-8' );
					}
				}
				$local_categories = array_values( array_unique( $local_categories ) );
			}
			
			// Also update in repo if it exists
			$repo = costudio_sites();
			if ( $repo && method_exists( $repo, 'set_categories' ) ) {
				$repo->set_categories( $site_key, $local_categories );
			}

			wp_send_json_success( array( 'categories' => $local_categories ) );
		}

		$url      = $in['url'];
		$user     = $in['user'];
		$password = $in['password'];

		// If editing a saved site, load stored credentials as fallback.
		if ( $site_key ) {
			$repo = costudio_sites();
			$cfg  = $repo ? $repo->get( (string) $site_key ) : null;
			if ( $cfg ) {
				$url  = $url  ?: (string) rtrim( ( $cfg['url']  ?? '' ), '/' );
				$user = $user ?: (string) ( $cfg['user'] ?? '' );

				// Decrypt stored password as fallback.
				if ( '' === $password && ! empty( $cfg['password'] ) ) {
					$stored = (string) $cfg['password'];
					if ( method_exists( $repo, 'decrypt_password' ) ) {
						$password = $repo->decrypt_password( $stored );
					} elseif ( class_exists( 'Costudio_Sites_Crypto' ) ) {
						$password = Costudio_Sites_Crypto::decrypt( $stored );
					} else {
						$password = base64_decode( $stored, true ) ?: $stored; // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
					}
				}
			}
		}

		if ( empty( $url ) ) {
			wp_send_json_error( __( 'Site URL is required.', 'contentosapp-studio' ) );
		}
		$url = rtrim( $url, '/' );

		// Auth header (optional for public WP categories endpoints).
		$auth_headers = ( ! empty( $user ) && '' !== $password )
			? array( 'Authorization' => 'Basic ' . base64_encode( "{$user}:{$password}" ) ) // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions
			: array();

		$categories  = array();
		$page        = 1;
		$total_pages = 1;

		do {
			$endpoint = $url . '/wp-json/wp/v2/categories?' . http_build_query( array(
				'per_page' => 100,
				'page'     => $page,
				'orderby'  => 'name',
				'order'    => 'asc',
			) );

			$response = wp_safe_remote_get( $endpoint, array(
				'timeout' => 20,
				'headers' => $auth_headers,
			) );

			if ( is_wp_error( $response ) ) {
				wp_send_json_error( array(
					'message' => __( 'Connection error:', 'contentosapp-studio' ) . ' ' . $response->get_error_message(),
				) );
			}

			$code = (int) wp_remote_retrieve_response_code( $response );
			if ( 200 !== $code ) {
				wp_send_json_error( array(
					/* translators: %d: HTTP status code */
					/* translators: %d: HTTP response status code. */
					'message' => sprintf( __( 'Site returned HTTP %d. Check the URL and credentials.', 'contentosapp-studio' ), $code ),
				) );
			}

			$data = json_decode( wp_remote_retrieve_body( $response ), true );
			if ( ! is_array( $data ) ) {
				break;
			}

			foreach ( $data as $cat ) {
				$cat_name = (string) ( $cat['name'] ?? '' );
				if (
					! empty( $cat_name )
					&& 'Uncategorized' !== $cat_name
					&& 'Sem categoria' !== $cat_name
				) {
					$categories[] = html_entity_decode( $cat_name, ENT_QUOTES, 'UTF-8' );
				}
			}

			$total_pages = (int) wp_remote_retrieve_header( $response, 'X-WP-TotalPages' );
			$page++;
		} while ( $page <= $total_pages && $page <= 5 );

		$categories = array_values( array_unique( $categories ) );

		// Persist categories on the saved site record if possible.
		if ( $site_key ) {
			$repo = costudio_sites();
			if ( $repo && method_exists( $repo, 'set_categories' ) ) {
				$repo->set_categories( (string) $site_key, $categories );
			}
		}

		wp_send_json_success( array( 'categories' => $categories ) );
	}
}
