<?php

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

class AIEO_SEO_Local_Business_Builder {

	
	private static $days = array(
		0 => 'https://schema.org/Sunday',
		1 => 'https://schema.org/Monday',
		2 => 'https://schema.org/Tuesday',
		3 => 'https://schema.org/Wednesday',
		4 => 'https://schema.org/Thursday',
		5 => 'https://schema.org/Friday',
		6 => 'https://schema.org/Saturday',
	);

	
	public static function build_nodes( $org_id ) {
		$out = array( 'nodes' => array(), 'refs' => array(), 'hq' => null );
		if ( ! class_exists( 'AIEO_Google_Reviews_Locations' ) ) {
			return $out;
		}
		$home      = trailingslashit( home_url() );
		$locations = AIEO_Google_Reviews_Locations::list_all( true ); 
		if ( empty( $locations ) ) {
			return $out;
		}
		foreach ( $locations as $loc ) {
			$node = self::node_for( $loc, $home, $org_id );
			if ( null === $node ) {
				continue; 
			}
			$out['nodes'][] = $node;
			$out['refs'][]  = array( '@id' => $node['@id'] );
			if ( ! empty( $loc['is_hq'] ) ) {
				$out['hq'] = $loc;
			}
		}
		if ( null === $out['hq'] && ! empty( $locations ) ) {
			$out['hq'] = $locations[0]; 
		}
		return $out;
	}

	
	private static function node_for( array $loc, $home, $org_id ) {
		$slug = isset( $loc['slug'] ) ? sanitize_title( (string) $loc['slug'] ) : '';
		if ( '' === $slug ) {
			return null;
		}
		$name = '' !== (string) ( $loc['label'] ?? '' ) ? (string) $loc['label'] : (string) ( $loc['google_name'] ?? '' );
		if ( '' === $name ) {
			return null;
		}
		$address = self::address_for( $loc );
		if ( empty( $address ) ) {
			return null; 
		}

		
		
		
		
		
		
		
		
		$page_url = class_exists( 'AIEO_SEO_Location_Page' ) ? (string) AIEO_SEO_Location_Page::url_for( $loc ) : '';
		$node = array(
			'@type'              => 'HealthAndBeautyBusiness',
			'@id'                => $home . '#location-' . $slug,
			'name'               => $name,
			'parentOrganization' => array( '@id' => $org_id ),
			'address'            => $address,
		);
		if ( '' !== $page_url ) {
			$node['url'] = $page_url;
		}

		if ( isset( $loc['lat'], $loc['lng'] ) && '' !== (string) $loc['lat'] && '' !== (string) $loc['lng'] ) {
			$node['geo'] = array(
				'@type'     => 'GeoCoordinates',
				'latitude'  => (float) $loc['lat'],
				'longitude' => (float) $loc['lng'],
			);
		}
		$phone = (string) ( $loc['phone'] ?? '' );
		if ( '' !== $phone ) {
			$node['telephone'] = $phone;
		}
		$price = (string) ( $loc['price_range'] ?? '' );
		if ( '' !== $price ) {
			$node['priceRange'] = $price;
		}
		$image = (string) ( $loc['image_url'] ?? '' );
		if ( '' !== $image ) {
			$node['image'] = $image;
		}

		
		$map = (string) ( $loc['gbp_url'] ?? '' );
		if ( '' === $map && class_exists( 'AIEO_Google_Reviews_Helpers' ) ) {
			$map = (string) AIEO_Google_Reviews_Helpers::maps_url( $loc );
		}
		if ( '' !== $map ) {
			$node['hasMap'] = $map;
			$node['sameAs'] = $map;
		}

		$hours = self::hours_for( $loc );
		if ( ! empty( $hours ) ) {
			$node['openingHoursSpecification'] = $hours;
		}
		return $node;
	}

	
	public static function address_for( array $loc ) {
		$street   = (string) ( $loc['street'] ?? '' );
		$locality = (string) ( $loc['locality'] ?? '' );
		$region   = (string) ( $loc['region'] ?? '' );
		$postal   = (string) ( $loc['postcode'] ?? '' );
		$country  = (string) ( $loc['country'] ?? '' );
		if ( '' === $street && '' === $locality ) {
			return array();
		}
		$addr = array( '@type' => 'PostalAddress' );
		if ( '' !== $street ) {
			$addr['streetAddress'] = $street;
		}
		if ( '' !== $locality ) {
			$addr['addressLocality'] = $locality;
		}
		if ( '' !== $region ) {
			$addr['addressRegion'] = $region;
		}
		if ( '' !== $postal ) {
			$addr['postalCode'] = $postal;
		}
		$addr['addressCountry'] = '' !== $country ? $country : 'GR';
		return $addr;
	}

	
	private static function hours_for( array $loc ) {
		$raw = (string) ( $loc['hours_json'] ?? '' );
		if ( '' === $raw ) {
			return array();
		}
		$periods = json_decode( $raw, true );
		if ( ! is_array( $periods ) ) {
			return array();
		}
		$specs = array();
		foreach ( $periods as $p ) {
			if ( ! isset( $p['open']['day'] ) ) {
				continue;
			}
			$day = (int) $p['open']['day'];
			if ( ! isset( self::$days[ $day ] ) ) {
				continue;
			}
			if ( isset( $p['close']['time'] ) ) {
				$opens  = self::fmt_time( isset( $p['open']['time'] ) ? (string) $p['open']['time'] : '' );
				$closes = self::fmt_time( (string) $p['close']['time'] );
			} else {
				
				$opens  = '00:00:00';
				$closes = '23:59:59';
			}
			if ( '' === $opens || '' === $closes ) {
				continue;
			}
			$specs[] = array(
				'@type'     => 'OpeningHoursSpecification',
				'dayOfWeek' => self::$days[ $day ],
				'opens'     => $opens,
				'closes'    => $closes,
			);
		}
		return $specs;
	}

	
	private static function fmt_time( $hhmm ) {
		$hhmm = preg_replace( '/\D/', '', (string) $hhmm );
		if ( strlen( (string) $hhmm ) < 4 ) {
			return '';
		}
		return substr( $hhmm, 0, 2 ) . ':' . substr( $hhmm, 2, 2 ) . ':00';
	}
}
