<?php
/**
 * Course Schema Class for BW AI Schema Pro
 *
 * @package BW_AI_Schema_Pro
 */

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

class BW_Schema_Course extends BW_Schema_Base {
	
	/**
	 * Generate course schema
	 */
	public function generate( $post, $type = 'Course' ) {
		// Base schema
		$schema = array(
			'@context' => 'https://schema.org',
			'@type' => $type,
		);
		
		// Add common properties
		$schema = array_merge( $schema, $this->get_common_properties( $post ) );
		
		// Add provider
		$provider = $this->get_provider_properties( $post );
		if ( ! empty( $provider ) ) {
			$schema['provider'] = $provider;
		}
		
		// Add instructor
		$instructor = $this->get_instructor_properties( $post );
		if ( ! empty( $instructor ) ) {
			$schema['instructor'] = $instructor;
		}
		
		// Add course mode
		$course_mode = get_post_meta( $post->ID, '_bw_schema_course_mode', true );
		if ( ! empty( $course_mode ) ) {
			$schema['courseMode'] = $course_mode;
		} else {
			$schema['courseMode'] = 'online';
		}
		
		// Add educational level
		$educational_level = get_post_meta( $post->ID, '_bw_schema_educational_level', true );
		if ( ! empty( $educational_level ) ) {
			$schema['educationalLevel'] = $educational_level;
		}
		
		// Add time required
		$time_required = get_post_meta( $post->ID, '_bw_schema_time_required', true );
		if ( ! empty( $time_required ) ) {
			$schema['timeRequired'] = $this->format_duration( $time_required );
		}
		
		// Add number of lessons
		$number_of_lessons = get_post_meta( $post->ID, '_bw_schema_number_of_lessons', true );
		if ( ! empty( $number_of_lessons ) ) {
			$schema['numberOfCredits'] = intval( $number_of_lessons );
		}
		
		// Add course code
		$course_code = get_post_meta( $post->ID, '_bw_schema_course_code', true );
		if ( ! empty( $course_code ) ) {
			$schema['courseCode'] = $course_code;
		}
		
		// Add course prerequisites
		$prerequisites = get_post_meta( $post->ID, '_bw_schema_course_prerequisites', true );
		if ( ! empty( $prerequisites ) && is_array( $prerequisites ) ) {
			$prereq_list = array();
			foreach ( $prerequisites as $prerequisite ) {
				$prereq_list[] = array(
					'@type' => 'Course',
					'name' => $prerequisite,
				);
			}
			$schema['coursePrerequisites'] = $prereq_list;
		}
		
		// Add educational credential awarded
		$credential_awarded = get_post_meta( $post->ID, '_bw_schema_credential_awarded', true );
		if ( ! empty( $credential_awarded ) ) {
			$schema['educationalCredentialAwarded'] = array(
				'@type' => 'EducationalOccupationalCredential',
				'name' => $credential_awarded,
			);
		}
		
		// Add competency required
		$competencies = get_post_meta( $post->ID, '_bw_schema_competency_required', true );
		if ( ! empty( $competencies ) && is_array( $competencies ) ) {
			$competency_list = array();
			foreach ( $competencies as $competency ) {
				$competency_list[] = array(
					'@type' => 'DefinedTerm',
					'name' => $competency,
				);
			}
			$schema['competencyRequired'] = $competency_list;
		}
		
		// Add teaches
		$teaches = get_post_meta( $post->ID, '_bw_schema_teaches', true );
		if ( ! empty( $teaches ) && is_array( $teaches ) ) {
			$teaches_list = array();
			foreach ( $teaches as $skill ) {
				$teaches_list[] = array(
					'@type' => 'DefinedTerm',
					'name' => $skill,
				);
			}
			$schema['teaches'] = $teaches_list;
		}
		
		// Add financial aid eligible
		$financial_aid = get_post_meta( $post->ID, '_bw_schema_financial_aid_eligible', true );
		if ( ! empty( $financial_aid ) ) {
			$schema['financialAidEligible'] = $financial_aid === 'yes';
		}
		
		// Add audience
		$audience = $this->get_audience_properties( $post );
		if ( ! empty( $audience ) ) {
			$schema['audience'] = $audience;
		}
		
		// Add aggregate rating
		$rating = $this->get_aggregate_rating( $post );
		if ( ! empty( $rating ) ) {
			$schema['aggregateRating'] = $rating;
		}
		
		// Add offers
		$offers = $this->get_course_offers( $post );
		if ( ! empty( $offers ) ) {
			$schema['offers'] = $offers;
		}
		
		// Add course instances
		$instances = $this->get_course_instances( $post );
		if ( ! empty( $instances ) ) {
			$schema['hasCourseInstance'] = $instances;
		}
		
		// Add syllabus sections
		$syllabus = $this->get_syllabus_sections( $post );
		if ( ! empty( $syllabus ) ) {
			$schema['syllabusSections'] = $syllabus;
		}
		
		// Add in language
		$in_language = get_post_meta( $post->ID, '_bw_schema_in_language', true );
		if ( ! empty( $in_language ) ) {
			$schema['inLanguage'] = $in_language;
		} else {
			$schema['inLanguage'] = get_locale();
		}
		
		// Add AI-optimized properties
		$schema = $this->add_ai_properties( $schema, $post );
		
		// Add specific properties based on course type
		switch ( $type ) {
			case 'OnlineCourse':
				$schema = $this->add_online_course_properties( $schema, $post );
				break;
		}
		
		return apply_filters( 'bw_schema_course', $schema, $post, $type );
	}
	
	/**
	 * Get provider properties
	 */
	private function get_provider_properties( $post ) {
		$provider_name = get_post_meta( $post->ID, '_bw_schema_provider_name', true );
		
		if ( empty( $provider_name ) ) {
			return $this->get_organization_properties();
		}
		
		$provider = array(
			'@type' => 'Organization',
			'name' => $provider_name,
		);
		
		$provider_url = get_post_meta( $post->ID, '_bw_schema_provider_url', true );
		if ( ! empty( $provider_url ) ) {
			$provider['url'] = $provider_url;
		}
		
		$provider_logo = get_post_meta( $post->ID, '_bw_schema_provider_logo', true );
		if ( ! empty( $provider_logo ) ) {
			$provider['logo'] = array(
				'@type' => 'ImageObject',
				'url' => $provider_logo,
			);
		}
		
		return $provider;
	}
	
	/**
	 * Get instructor properties
	 */
	private function get_instructor_properties( $post ) {
		$instructor_name = get_post_meta( $post->ID, '_bw_schema_instructor_name', true );
		
		if ( empty( $instructor_name ) ) {
			return $this->get_author_properties( $post->post_author );
		}
		
		$instructor = array(
			'@type' => 'Person',
			'name' => $instructor_name,
		);
		
		$instructor_url = get_post_meta( $post->ID, '_bw_schema_instructor_url', true );
		if ( ! empty( $instructor_url ) ) {
			$instructor['url'] = $instructor_url;
		}
		
		$instructor_image = get_post_meta( $post->ID, '_bw_schema_instructor_image', true );
		if ( ! empty( $instructor_image ) ) {
			$instructor['image'] = $instructor_image;
		}
		
		$instructor_description = get_post_meta( $post->ID, '_bw_schema_instructor_description', true );
		if ( ! empty( $instructor_description ) ) {
			$instructor['description'] = $instructor_description;
		}
		
		$instructor_credentials = get_post_meta( $post->ID, '_bw_schema_instructor_credentials', true );
		if ( ! empty( $instructor_credentials ) && is_array( $instructor_credentials ) ) {
			$credentials = array();
			foreach ( $instructor_credentials as $credential ) {
				$credentials[] = array(
					'@type' => 'EducationalOccupationalCredential',
					'name' => $credential,
				);
			}
			$instructor['hasCredential'] = $credentials;
		}
		
		return $instructor;
	}
	
	/**
	 * Format duration to ISO 8601
	 */
	private function format_duration( $duration ) {
		// If already in ISO 8601 format
		if ( strpos( $duration, 'P' ) === 0 ) {
			return $duration;
		}
		
		// If in hours
		if ( is_numeric( $duration ) ) {
			return 'PT' . $duration . 'H';
		}
		
		// If contains "hours" or "weeks"
		if ( preg_match( '/(\d+)\s*(hours?|weeks?|days?|months?)/', $duration, $matches ) ) {
			$value = intval( $matches[1] );
			$unit = $matches[2];
			
			switch ( $unit ) {
				case 'hour':
				case 'hours':
					return 'PT' . $value . 'H';
				case 'day':
				case 'days':
					return 'P' . $value . 'D';
				case 'week':
				case 'weeks':
					return 'P' . $value . 'W';
				case 'month':
				case 'months':
					return 'P' . $value . 'M';
			}
		}
		
		return $duration;
	}
	
	/**
	 * Get audience properties
	 */
	private function get_audience_properties( $post ) {
		$audience = array(
			'@type' => 'EducationalAudience',
		);
		
		$audience_type = get_post_meta( $post->ID, '_bw_schema_audience_type', true );
		if ( ! empty( $audience_type ) ) {
			$audience['audienceType'] = $audience_type;
		}
		
		$educational_role = get_post_meta( $post->ID, '_bw_schema_educational_role', true );
		if ( ! empty( $educational_role ) ) {
			$audience['educationalRole'] = $educational_role;
		}
		
		return count( $audience ) > 1 ? $audience : null;
	}
	
	/**
	 * Get aggregate rating
	 */
	private function get_aggregate_rating( $post ) {
		$rating_value = get_post_meta( $post->ID, '_bw_schema_rating_value', true );
		$rating_count = get_post_meta( $post->ID, '_bw_schema_rating_count', true );
		
		if ( empty( $rating_value ) || empty( $rating_count ) ) {
			return null;
		}
		
		return array(
			'@type' => 'AggregateRating',
			'ratingValue' => floatval( $rating_value ),
			'reviewCount' => intval( $rating_count ),
			'bestRating' => 5,
			'worstRating' => 1,
		);
	}
	
	/**
	 * Get course offers
	 */
	private function get_course_offers( $post ) {
		$offer = array(
			'@type' => 'Offer',
		);
		
		// Price
		$price = get_post_meta( $post->ID, '_bw_schema_price', true );
		if ( ! empty( $price ) ) {
			$offer['price'] = $price;
		} else {
			$offer['price'] = '0';
		}
		
		// Currency
		$currency = get_post_meta( $post->ID, '_bw_schema_price_currency', true );
		if ( ! empty( $currency ) ) {
			$offer['priceCurrency'] = $currency;
		} else {
			$offer['priceCurrency'] = 'USD';
		}
		
		// Availability
		$offer['availability'] = 'https://schema.org/InStock';
		
		// Valid from
		$valid_from = get_post_meta( $post->ID, '_bw_schema_valid_from', true );
		if ( ! empty( $valid_from ) ) {
			$offer['validFrom'] = $valid_from;
		}
		
		// Category
		$offer['category'] = 'Educational';
		
		// URL
		$offer['url'] = get_permalink( $post );
		
		return $offer;
	}
	
	/**
	 * Get course instances
	 */
	private function get_course_instances( $post ) {
		$instances = get_post_meta( $post->ID, '_bw_schema_course_instances', true );
		
		if ( empty( $instances ) || ! is_array( $instances ) ) {
			// Create a default instance
			$instance = array(
				'@type' => 'CourseInstance',
				'courseMode' => get_post_meta( $post->ID, '_bw_schema_course_mode', true ) ?: 'online',
			);
			
			$start_date = get_post_meta( $post->ID, '_bw_schema_start_date', true );
			if ( ! empty( $start_date ) ) {
				$instance['startDate'] = $start_date;
			}
			
			$end_date = get_post_meta( $post->ID, '_bw_schema_end_date', true );
			if ( ! empty( $end_date ) ) {
				$instance['endDate'] = $end_date;
			}
			
			$course_workload = get_post_meta( $post->ID, '_bw_schema_course_workload', true );
			if ( ! empty( $course_workload ) ) {
				$instance['courseWorkload'] = $course_workload;
			}
			
			return array( $instance );
		}
		
		$instance_list = array();
		foreach ( $instances as $instance ) {
			$course_instance = array(
				'@type' => 'CourseInstance',
			);
			
			if ( ! empty( $instance['courseMode'] ) ) {
				$course_instance['courseMode'] = $instance['courseMode'];
			}
			
			if ( ! empty( $instance['startDate'] ) ) {
				$course_instance['startDate'] = $instance['startDate'];
			}
			
			if ( ! empty( $instance['endDate'] ) ) {
				$course_instance['endDate'] = $instance['endDate'];
			}
			
			if ( ! empty( $instance['courseWorkload'] ) ) {
				$course_instance['courseWorkload'] = $instance['courseWorkload'];
			}
			
			if ( ! empty( $instance['instructor'] ) ) {
				$course_instance['instructor'] = array(
					'@type' => 'Person',
					'name' => $instance['instructor'],
				);
			}
			
			$instance_list[] = $course_instance;
		}
		
		return $instance_list;
	}
	
	/**
	 * Get syllabus sections
	 */
	private function get_syllabus_sections( $post ) {
		$sections = get_post_meta( $post->ID, '_bw_schema_syllabus_sections', true );
		
		if ( empty( $sections ) || ! is_array( $sections ) ) {
			return null;
		}
		
		$syllabus_list = array();
		foreach ( $sections as $section ) {
			$syllabus_section = array(
				'@type' => 'Syllabus',
			);
			
			if ( ! empty( $section['name'] ) ) {
				$syllabus_section['name'] = $section['name'];
			}
			
			if ( ! empty( $section['description'] ) ) {
				$syllabus_section['description'] = $section['description'];
			}
			
			if ( ! empty( $section['timeRequired'] ) ) {
				$syllabus_section['timeRequired'] = $this->format_duration( $section['timeRequired'] );
			}
			
			$syllabus_list[] = $syllabus_section;
		}
		
		return $syllabus_list;
	}
	
	/**
	 * Add online course specific properties
	 */
	private function add_online_course_properties( $schema, $post ) {
		// Course delivery format
		$delivery_format = get_post_meta( $post->ID, '_bw_schema_course_delivery_format', true );
		if ( ! empty( $delivery_format ) ) {
			$schema['courseDeliveryFormat'] = $delivery_format;
		}
		
		// Platform
		$platform = get_post_meta( $post->ID, '_bw_schema_course_platform', true );
		if ( ! empty( $platform ) ) {
			$schema['educationalPlatform'] = $platform;
		}
		
		// Video duration
		$video_duration = get_post_meta( $post->ID, '_bw_schema_total_video_duration', true );
		if ( ! empty( $video_duration ) ) {
			$schema['totalVideoDuration'] = $this->format_duration( $video_duration );
		}
		
		// Requires subscription
		$requires_subscription = get_post_meta( $post->ID, '_bw_schema_requires_subscription', true );
		if ( $requires_subscription === 'yes' ) {
			$schema['requiresSubscription'] = true;
		}
		
		// Certificate available
		$certificate_available = get_post_meta( $post->ID, '_bw_schema_certificate_available', true );
		if ( $certificate_available === 'yes' ) {
			$schema['hasCertificate'] = true;
		}
		
		return $schema;
	}
}