<?php

namespace SugarCalendarBookings\Migration\Sources\Amelia\Mappers;

use SugarCalendarBookings\Migration\AbstractMapper;
use SugarCalendarBookings\Support\Helpers\AddressParser;

/**
 * Location Mapper.
 *
 * @since 1.3.0
 */
class LocationMapper extends AbstractMapper {

	/**
	 * Map Amelia location to SCB format.
	 *
	 * @since 1.3.0
	 *
	 * @param object               $raw     Raw Amelia data.
	 * @param array<string, mixed> $context Context.
	 *
	 * @return array<string, mixed>
	 */
	public function map( object $raw, array $context = [] ): array {

		$sanitized = $this->extract_and_sanitize(
			$raw,
			[
				'name'              => [
					'source'  => 'name',
					'default' => 'Untitled Location',
					'rule'    => 'string',
				],
				'address'           => [
					'source'  => 'address',
					'default' => '',
					'rule'    => 'string',
				],
				'phone'             => [
					'source'  => 'phone',
					'default' => '',
					'rule'    => 'string',
				],
				'latitude'          => [
					'source'  => 'latitude',
					'default' => null,
					'rule'    => 'nullable|numeric',
				],
				'longitude'         => [
					'source'  => 'longitude',
					'default' => null,
					'rule'    => 'nullable|numeric',
				],
				'status'            => [
					'source'  => 'status',
					'default' => 'visible',
					'rule'    => 'string',
				],
				'country_phone_iso' => [
					'source'  => 'countryPhoneIso',
					'default' => '',
					'rule'    => 'string',
				],
				'id'                => [
					'source'  => 'id',
					'default' => 0,
					'rule'    => 'numeric',
				],
			]
		);

		// Parse address string into structured components.
		$country_hint = ! empty( $sanitized['country_phone_iso'] )
			? strtoupper( $sanitized['country_phone_iso'] )
			: 'US';

		$parsed_address = AddressParser::parse( $sanitized['address'], $country_hint );

		$mapped = [
			'name'         => $sanitized['name'],
			'address'      => $parsed_address['address'],
			'address2'     => $parsed_address['address2'],
			'city'         => $parsed_address['city'],
			'region'       => $parsed_address['region'],
			'postal_code'  => $parsed_address['postal_code'],
			'country_code' => $parsed_address['country_code'],
			'status'       => $this->map_entity_status( $sanitized['status'] ),
			'author_id'    => $context['author_id'] ?? 1,
			'created_at'   => current_time( 'mysql' ),
			'updated_at'   => current_time( 'mysql' ),
			// Store original Amelia ID for cross-entity lookup during service/appointment migration.
			'_amelia_id'   => (int) $sanitized['id'],
		];

		// Optional fields.
		if ( ! empty( $sanitized['phone'] ) ) {
			$mapped['phone'] = $sanitized['phone'];
		}

		if ( ! empty( $sanitized['latitude'] ) ) {
			$mapped['latitude'] = (float) $sanitized['latitude'];
		}

		if ( ! empty( $sanitized['longitude'] ) ) {
			$mapped['longitude'] = (float) $sanitized['longitude'];
		}

		return $mapped;
	}
}
