<?php
/**
 * Business logic service for Locations & Rooms schema data
 *
 * Handles multi-location management and rooms/accommodations for the organization.
 * This service covers:
 * - Multiple location CRUD operations
 * - Service areas (company-wide and per-location)
 * - Rooms/Accommodations (v2.4.0+)
 *
 * @package BW_Schema
 * @since 3.0.0-babel
 */

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

class BW_Schema_Service_Locations {

	/**
	 * Prefix for all options (will be bw_schema_* in v3.0.0+)
	 * For now, keeps backward compatibility with bw_schema_*
	 *
	 * @var string
	 */
	const PREFIX = 'bw_schema_';

	// ====== LOCATIONS ======

	/**
	 * Get all locations
	 *
	 * @return array Array of location records
	 */
	public static function get_locations() {
		return get_option( self::PREFIX . 'locations', array() );
	}

	/**
	 * Get a single location by ID
	 *
	 * @param string $location_id Location ID
	 * @return array|null Location data or null if not found
	 */
	public static function get_location( $location_id ) {
		$locations = self::get_locations();
		foreach ( $locations as $location ) {
			if ( $location['id'] === $location_id ) {
				return $location;
			}
		}
		return null;
	}

	/**
	 * Add a new location
	 *
	 * @param array $location_data Location data (name, address, phone, etc.)
	 * @return array|WP_Error Array with location ID on success, WP_Error on failure
	 */
	public static function add_location( $location_data ) {
		// Validate
		$validation = self::validate_location( $location_data );
		if ( is_wp_error( $validation ) ) {
			return $validation;
		}

		// Sanitize
		$sanitized = self::sanitize_location( $location_data );

		// Generate unique ID
		$location_id = wp_generate_uuid4();
		$sanitized['id'] = $location_id;

		// Add to locations array
		$locations = self::get_locations();
		$locations[] = $sanitized;

		// Save
		update_option( self::PREFIX . 'locations', $locations );

		// Clear caches
		self::clear_cache();

		return array( 'id' => $location_id, 'success' => true );
	}

	/**
	 * Update a location
	 *
	 * @param string $location_id Location ID
	 * @param array  $location_data Updated location data
	 * @return array|WP_Error Success array or WP_Error
	 */
	public static function update_location( $location_id, $location_data ) {
		// Validate
		$validation = self::validate_location( $location_data );
		if ( is_wp_error( $validation ) ) {
			return $validation;
		}

		// Find and update
		$locations = self::get_locations();
		$found = false;
		foreach ( $locations as &$location ) {
			if ( $location['id'] === $location_id ) {
				$sanitized = self::sanitize_location( $location_data );
				$sanitized['id'] = $location_id; // Preserve ID
				$location = $sanitized;
				$found = true;
				break;
			}
		}

		if ( ! $found ) {
			return new WP_Error( 'location_not_found', __( 'Location not found.', 'bw-schema' ) );
		}

		// Save
		update_option( self::PREFIX . 'locations', $locations );

		// Clear caches
		self::clear_cache();

		return array( 'success' => true );
	}

	/**
	 * Delete a location
	 *
	 * @param string $location_id Location ID
	 * @return array|WP_Error Success array or WP_Error
	 */
	public static function delete_location( $location_id ) {
		$locations = self::get_locations();
		$locations = array_filter(
			$locations,
			function( $loc ) use ( $location_id ) {
				return $loc['id'] !== $location_id;
			}
		);

		update_option( self::PREFIX . 'locations', array_values( $locations ) );

		// Clear caches
		self::clear_cache();

		return array( 'success' => true );
	}

	/**
	 * Validate location data
	 *
	 * @param array $data Location data to validate
	 * @return bool|WP_Error True if valid, WP_Error if not
	 */
	public static function validate_location( $data ) {
		if ( empty( $data['name'] ) ) {
			return new WP_Error( 'missing_name', __( 'Location name is required.', 'bw-schema' ) );
		}

		if ( ! empty( $data['telephone'] ) && ! preg_match( '/^\+?[0-9\s\-\.\(\)]+$/', $data['telephone'] ) ) {
			return new WP_Error( 'invalid_phone', __( 'Location phone number format is invalid.', 'bw-schema' ) );
		}

		if ( ! empty( $data['email'] ) && ! is_email( $data['email'] ) ) {
			return new WP_Error( 'invalid_email', __( 'Location email is invalid.', 'bw-schema' ) );
		}

		return true;
	}

	/**
	 * Sanitize location data
	 *
	 * @param array $data Location data to sanitize
	 * @return array Sanitized data
	 */
	public static function sanitize_location( $data ) {
		// Safely handle areas array - must exist and be an array
		$areas = array();
		if ( isset( $data['areas'] ) && is_array( $data['areas'] ) ) {
			$areas = array_map( 'sanitize_text_field', $data['areas'] );
		}

		return array(
			'name'      => sanitize_text_field( $data['name'] ?? '' ),
			'type'      => sanitize_text_field( $data['type'] ?? 'Place' ),
			'street'    => sanitize_text_field( $data['street'] ?? '' ),
			'city'      => sanitize_text_field( $data['city'] ?? '' ),
			'region'    => sanitize_text_field( $data['region'] ?? '' ),
			'postal'    => sanitize_text_field( $data['postal'] ?? '' ),
			'country'   => sanitize_text_field( $data['country'] ?? '' ),
			'lat'       => floatval( $data['lat'] ?? 0 ),
			'lng'       => floatval( $data['lng'] ?? 0 ),
			'telephone' => sanitize_text_field( $data['telephone'] ?? '' ),
			'email'     => sanitize_email( $data['email'] ?? '' ),
			'url'       => esc_url_raw( $data['url'] ?? '' ),
			'use_main_hours' => (bool) ( $data['use_main_hours'] ?? false ),
			'areas'     => $areas,
		);
	}

	// ====== SERVICE AREAS ======

	/**
	 * Get all service areas
	 *
	 * @return array Array of service area records (company-wide + per-location)
	 */
	public static function get_service_areas() {
		return get_option( self::PREFIX . 'service_areas', array() );
	}

	/**
	 * Add a service area
	 *
	 * @param array $area Service area data (name, type, etc.)
	 * @return array|WP_Error Success array with area ID or WP_Error
	 */
	public static function add_service_area( $area ) {
		$area_id = wp_generate_uuid4();
		$area['id'] = $area_id;

		$areas = self::get_service_areas();
		$areas[] = $area;

		update_option( self::PREFIX . 'service_areas', $areas );
		self::clear_cache();

		return array( 'id' => $area_id, 'success' => true );
	}

	/**
	 * Delete a service area
	 *
	 * @param string $area_id Service area ID
	 * @return array|WP_Error Success array or WP_Error
	 */
	public static function delete_service_area( $area_id ) {
		$areas = get_option( self::PREFIX . 'service_areas', array() );
		$areas = array_filter(
			$areas,
			function( $area ) use ( $area_id ) {
				return $area['id'] !== $area_id;
			}
		);

		update_option( self::PREFIX . 'service_areas', array_values( $areas ) );
		self::clear_cache();

		return array( 'success' => true );
	}

	// ====== ROOMS / ACCOMMODATIONS ======

	/**
	 * Get room post type slug
	 *
	 * @return string Room post type slug or empty string if not configured
	 */
	public static function get_room_post_type() {
		return get_option( self::PREFIX . 'room_post_type', '' );
	}

	/**
	 * Set room post type
	 *
	 * @param string $post_type Room post type slug
	 * @return bool Success
	 */
	public static function set_room_post_type( $post_type ) {
		update_option( self::PREFIX . 'room_post_type', sanitize_key( $post_type ) );
		self::clear_cache();
		return true;
	}

	/**
	 * Get accommodation module settings
	 *
	 * Returns settings for the rooms/accommodations feature:
	 * - Currency (USD, EUR, etc.)
	 * - Rate unit (DAY, NIGHT, etc.)
	 * - Rate stale threshold (days)
	 *
	 * @return array Accommodation settings
	 */
	public static function get_accommodation_settings() {
		return wp_parse_args(
			get_option( self::PREFIX . 'accommodation', array() ),
			array(
				'currency'        => 'USD',
				'rate_unit'       => 'DAY',
				'rate_stale_days' => 180,
			)
		);
	}

	/**
	 * Save accommodation settings
	 *
	 * @param array $settings Accommodation settings (currency, rate_unit, rate_stale_days)
	 * @return bool Success
	 */
	public static function save_accommodation_settings( $settings ) {
		$sanitized = array(
			'currency'        => sanitize_text_field( $settings['currency'] ?? 'USD' ),
			'rate_unit'       => sanitize_text_field( $settings['rate_unit'] ?? 'DAY' ),
			'rate_stale_days' => absint( $settings['rate_stale_days'] ?? 180 ),
		);

		update_option( self::PREFIX . 'accommodation', $sanitized );
		self::clear_cache();

		return true;
	}

	/**
	 * Check if accommodations are enabled
	 *
	 * @return bool True if room post type is configured
	 */
	public static function is_accommodations_enabled() {
		return ! empty( self::get_room_post_type() );
	}

	// ====== HELPERS ======

	/**
	 * Clear related caches
	 *
	 * @return void
	 */
	private static function clear_cache() {
		if ( class_exists( 'BW_Schema_Cache' ) ) {
			BW_Schema_Cache::clear_all();
		}
	}

	/**
	 * Get location count
	 *
	 * @return int Number of configured locations
	 */
	public static function get_location_count() {
		return count( self::get_locations() );
	}

	/**
	 * Check if locations are configured
	 *
	 * @return bool True if at least one location exists
	 */
	public static function has_locations() {
		return self::get_location_count() > 0;
	}

	/**
	 * Check if current business type supports multiple locations
	 *
	 * Some business types are inherently multi-location (chains, networks)
	 * while others are single-location (solo practitioners).
	 *
	 * @return bool True if locations section should be shown
	 */
	public static function should_show_locations_section() {
		$business_type = get_option( 'bw_schema_business_type', '' );

		// Business types that support/require multiple locations
		$multi_location_types = array(
			// Accommodation
			'hotel', 'resort', 'bedandbreakfast', 'hostel', 'campground',
			// Food & Beverage
			'restaurant', 'cafe', 'bar', 'bakery', 'brewery', 'icecream',
			// Medical & Healthcare
			'hospital', 'clinic', 'pharmacy', 'veterinary',
			// Retail
			'bookstore', 'clothingstore', 'electronicsstore', 'grocerystore', 'hardwarestore', 'toysstore',
			// Professional Services
			'attorney', 'accountant', 'insuranceagency', 'consulting',
			// Real Estate
			'realestateagent', 'realestatebiz',
			// Automotive
			'autorepair', 'autorental', 'carwash', 'gasstation',
			// Entertainment
			'movietheater', 'artgallery', 'nightclub', 'bowling', 'sportsfacility',
			// Beauty
			'spa', 'hairdresser', 'tattoo',
			// Education
			'university', 'highschool', 'middleschool', 'preschool', 'library',
			// Finance
			'bank', 'creditunion',
			// Services
			'cleaningservice', 'deliveryservice', 'laundry', 'movingcompany', 'plumber',
		);

		return in_array( $business_type, $multi_location_types, true );
	}
}
