<?php
/**
 * Organization schema type
 *
 * Outputs schema.org/Organization markup for the site's business information.
 *
 * @package BW_Schema
 * @since 3.0.0-babel
 */

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

class BW_Schema_Schema_Organization extends BW_Schema_Schema_Base {

	/**
	 * Schema type
	 *
	 * @var string
	 */
	protected $type = 'Organization';

	/**
	 * Build the organization schema
	 *
	 * @return void
	 */
	protected function build() {
		// Get organization data from service (if available)
		if ( ! class_exists( 'BW_Schema_Service_Organization' ) ) {
			// Service not loaded - can happen on WP-CLI or early hooks
			return;
		}

		try {
			$org = BW_Schema_Service_Organization::get();
		} catch ( Throwable $e ) {
			// Service call failed, bail gracefully
			return;
		}

		// Check if we got valid data
		if ( empty( $org ) || ! is_array( $org ) ) {
			return;
		}

		// Set required properties (keys match BW_Schema_Service_Organization contract)
		$this->set( 'name', $org['name'] ?? '' );
		$this->set( 'url', ! empty( $org['url'] ) ? $org['url'] : $this->get_site_url() );

		// Logo (stored as a URL by the service)
		if ( ! empty( $org['logo'] ) ) {
			$this->set_nested( 'logo', array(
				'@type' => 'ImageObject',
				'url'   => esc_url_raw( $org['logo'] ),
			) );
		}

		// Contact info
		$this->set_contact_info( $org );

		// Social profiles (service stores a sameAs array of URLs)
		if ( ! empty( $org['sameAs'] ) && is_array( $org['sameAs'] ) ) {
			$profiles = array_values( array_filter( array_map( 'esc_url_raw', $org['sameAs'] ) ) );
			if ( ! empty( $profiles ) ) {
				$this->set( 'sameAs', $profiles );
			}
		}

		// Description
		if ( ! empty( $org['description'] ) ) {
			$this->set( 'description', wp_strip_all_tags( $org['description'] ) );
		}

		// Alternate / legal names
		if ( ! empty( $org['alternateName'] ) ) {
			$this->set( 'alternateName', $org['alternateName'] );
		}
		if ( ! empty( $org['legalName'] ) ) {
			$this->set( 'legalName', $org['legalName'] );
		}

		// Slogan
		if ( ! empty( $org['slogan'] ) ) {
			$this->set( 'slogan', $org['slogan'] );
		}

		// Business type is stored as its own option (not inside org data)
		$business_type = get_option( 'bw_schema_business_type', '' );
		if ( ! empty( $business_type ) ) {
			$this->type = $this->map_business_type( $business_type );
			$this->schema['@type'] = $this->type;
		}
	}

	/**
	 * Set contact information
	 *
	 * @param array $org Organization data
	 * @return void
	 */
	private function set_contact_info( $org ) {
		$contact_point = array(
			'@type'       => 'ContactPoint',
			'contactType' => 'Customer Service',
		);

		// Email
		if ( ! empty( $org['email'] ) ) {
			$contact_point['email'] = $org['email'];
		}

		// Phone
		if ( ! empty( $org['telephone'] ) ) {
			$contact_point['telephone'] = $org['telephone'];
		}

		// Only set if we have at least one contact method
		if ( count( $contact_point ) > 2 ) {
			$this->set_nested( 'contactPoint', $contact_point );
		}

		// Also set phone at root level for LocalBusiness compatibility
		if ( ! empty( $org['telephone'] ) ) {
			$this->set( 'telephone', $org['telephone'] );
		}
	}

	/**
	 * Map business type to schema.org type
	 *
	 * Delegates to the Organization service, which owns the canonical
	 * category/type → schema.org type mapping.
	 *
	 * @param string $business_type Business type slug
	 * @return string Schema.org type
	 */
	private function map_business_type( $business_type ) {
		$category = get_option( 'bw_schema_business_category', '' );

		if ( $category && method_exists( 'BW_Schema_Service_Organization', 'get_schema_type' ) ) {
			$schema_type = BW_Schema_Service_Organization::get_schema_type( $category, $business_type );
			if ( ! empty( $schema_type ) ) {
				return $schema_type;
			}
		}

		return 'Organization';
	}

	/**
	 * Validate organization schema
	 *
	 * Organization requires at least a name.
	 *
	 * @return array Validation errors
	 */
	public function validate() {
		$errors = parent::validate();

		// Check required name property
		if ( ! $this->has_required( array( 'name' ) ) ) {
			$errors[] = 'Organization schema requires a name';
		}

		return $errors;
	}
}
