<?php

namespace SerpIQ\Gsc;

use SerpIQ\Helpers\Options;

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

final class Property_Detector {
	private static ?Property_Detector $instance = null;

	public static function instance(): Property_Detector {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Detects the only allowed property (site host) and stores it.
	 *
	 * @return string|\WP_Error
	 */
	public function detect_and_store() {
		$property = $this->detect();
		if ( is_wp_error( $property ) ) {
			delete_option( Options::google_property_key() );
			return $property;
		}

		update_option( Options::google_property_key(), $property, false );
		return $property;
	}

	/**
	 * @return string|\WP_Error
	 */
	public function detect() {
		$client = OAuth::instance()->client();
		if ( is_wp_error( $client ) ) {
			return $client;
		}

		$sites = $this->list_sites( $client );
		if ( is_wp_error( $sites ) ) {
			return $sites;
		}

		$host = (string) wp_parse_url( home_url( '/' ), PHP_URL_HOST );
		$host = strtolower( $host );
		$host_no_www = preg_replace( '/^www\./', '', $host );
		$host_with_www = 'www.' . $host_no_www;

		$candidates = array(
			'sc-domain:' . $host_no_www,
			'sc-domain:' . $host_with_www,
			'https://' . $host_no_www . '/',
			'http://' . $host_no_www . '/',
			'https://' . $host_with_www . '/',
			'http://' . $host_with_www . '/',
		);

		foreach ( $candidates as $candidate ) {
			if ( in_array( $candidate, $sites, true ) ) {
				return $candidate;
			}
		}

		return new \WP_Error(
			'serpiq_property_not_found',
			__( 'This site property was not found in Google Search Console for the connected account. Add this site in search.google.com/search-console and verify it.', 'seotune-search-insights' )
		);
	}

	/**
	 * @return array<int,string>|\WP_Error
	 */
	private function list_sites( $client ) {
		$service = null;
		if ( class_exists( '\Google_Service_SearchConsole' ) ) {
			$service = new \Google_Service_SearchConsole( $client );
		} elseif ( class_exists( '\Google_Service_Webmasters' ) ) {
			$service = new \Google_Service_Webmasters( $client );
		} else {
			return new \WP_Error( 'serpiq_missing_gsc_service', __( 'Search Console service class not found.', 'seotune-search-insights' ) );
		}

		$sites_response = null;
		if ( isset( $service->sites ) ) {
			if ( method_exists( $service->sites, 'listSites' ) ) {
				$sites_response = $service->sites->listSites();
			} elseif ( method_exists( $service->sites, 'listSitesSites' ) ) {
				$sites_response = $service->sites->listSitesSites();
			}
		}

		if ( ! $sites_response ) {
			return new \WP_Error( 'serpiq_sites_list_failed', __( 'Unable to list Search Console properties.', 'seotune-search-insights' ) );
		}

		$entries = array();
		if ( is_object( $sites_response ) && method_exists( $sites_response, 'getSiteEntry' ) ) {
			$entries = $sites_response->getSiteEntry();
		} elseif ( is_object( $sites_response ) && isset( $sites_response->siteEntry ) ) {
			$entries = $sites_response->siteEntry;
		}

		$urls = array();
		if ( is_array( $entries ) ) {
			foreach ( $entries as $entry ) {
				if ( is_object( $entry ) && method_exists( $entry, 'getSiteUrl' ) ) {
					$urls[] = (string) $entry->getSiteUrl();
				} elseif ( is_array( $entry ) && isset( $entry['siteUrl'] ) ) {
					$urls[] = (string) $entry['siteUrl'];
				} elseif ( is_object( $entry ) && isset( $entry->siteUrl ) ) {
					$urls[] = (string) $entry->siteUrl;
				}
			}
		}

		return array_values( array_unique( array_filter( $urls ) ) );
	}
}

