<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class DC_V2_Shipping_Countries {

	const SUPPORTED = array( 'CL', 'MX', 'PE', 'CO', 'AR', 'BR', 'ES' );

	public static function default_country() {
		if ( function_exists( 'WC' ) && WC()->countries ) {
			$base = WC()->countries->get_base_country();
			if ( in_array( $base, self::SUPPORTED, true ) ) {
				return $base;
			}
		}
		return 'CL';
	}

	public static function sanitize_country( $code ) {
		$code = strtoupper( sanitize_text_field( (string) $code ) );
		return in_array( $code, self::SUPPORTED, true ) ? $code : self::default_country();
	}

	public static function countries_list() {
		$out = array();
		$labels = function_exists( 'WC' ) && WC()->countries ? WC()->countries->get_countries() : array();
		foreach ( self::SUPPORTED as $code ) {
			$out[] = array(
				'code'  => $code,
				'label' => $labels[ $code ] ?? $code,
			);
		}
		return $out;
	}

	public static function get_config() {
		$fields = array();
		foreach ( self::SUPPORTED as $code ) {
			$fields[ $code ] = self::fields_for_country( $code );
		}
		return array(
			'defaultCountry' => self::default_country(),
			'countries'      => self::countries_list(),
			'fields'         => $fields,
		);
	}

	public static function get_states( $country ) {
		$country = self::sanitize_country( $country );
		$out     = array();
		foreach ( self::get_states_raw( $country ) as $code => $label ) {
			$out[] = array( 'code' => $code, 'label' => $label );
		}
		return $out;
	}

	public static function get_localities( $country, $state ) {
		$country = self::sanitize_country( $country );
		$state   = sanitize_text_field( (string) $state );
		if ( 'CL' === $country && $state ) {
			return amispet_dc_comunas_for_region( $state );
		}
		return array();
	}

	public static function normalize_input( $shipping ) {
		if ( ! is_array( $shipping ) ) {
			$shipping = array();
		}
		if ( ! empty( $shipping['region'] ) && empty( $shipping['state'] ) ) {
			$shipping['state'] = $shipping['region'];
		}
		if ( ! empty( $shipping['comuna'] ) && empty( $shipping['city'] ) ) {
			$shipping['city'] = $shipping['comuna'];
		}
		unset( $shipping['region'], $shipping['comuna'] );
		$shipping['country'] = self::sanitize_country( $shipping['country'] ?? '' );
		return $shipping;
	}

	public static function validate( $shipping ) {
		$shipping = self::normalize_input( $shipping );
		$base     = array( 'name', 'phone', 'email', 'address', 'country' );
		foreach ( $base as $key ) {
			if ( empty( $shipping[ $key ] ) || ! is_string( $shipping[ $key ] ) || trim( $shipping[ $key ] ) === '' ) {
				return new WP_Error( 'validation', __( 'Complete shipping details.', 'order-from-dm' ), array( 'status' => 400 ) );
			}
		}
		if ( ! is_email( $shipping['email'] ) ) {
			return new WP_Error( 'validation', __( 'Invalid email address.', 'order-from-dm' ), array( 'status' => 400 ) );
		}
		$phone_digits = preg_replace( '/\D+/', '', $shipping['phone'] );
		if ( strlen( $phone_digits ) < 8 || strlen( $phone_digits ) > 15 ) {
			return new WP_Error( 'validation', __( 'Enter a valid phone number.', 'order-from-dm' ), array( 'status' => 400 ) );
		}
		foreach ( self::fields_for_country( $shipping['country'] ) as $field ) {
			if ( empty( $field['required'] ) ) {
				continue;
			}
			$key = $field['key'];
			if ( empty( $shipping[ $key ] ) || ! is_string( $shipping[ $key ] ) || trim( $shipping[ $key ] ) === '' ) {
				return new WP_Error( 'validation', __( 'Complete shipping details.', 'order-from-dm' ), array( 'status' => 400 ) );
			}
		}
		return true;
	}

	public static function to_wc_address( $shipping ) {
		$shipping = self::normalize_input( $shipping );
		$name     = sanitize_text_field( $shipping['name'] );
		$parts    = preg_split( '/\s+/', $name, 2 );
		return array(
			'first_name' => $parts[0] ?? $name,
			'last_name'  => $parts[1] ?? '',
			'email'      => sanitize_email( $shipping['email'] ),
			'phone'      => sanitize_text_field( $shipping['phone'] ),
			'address_1'  => sanitize_text_field( $shipping['address'] ),
			'city'       => sanitize_text_field( $shipping['city'] ?? '' ),
			'state'      => sanitize_text_field( $shipping['state'] ?? '' ),
			'postcode'   => sanitize_text_field( $shipping['postcode'] ?? '' ),
			'country'    => $shipping['country'],
		);
	}

	private static function get_states_raw( $country ) {
		if ( function_exists( 'WC' ) && WC()->countries ) {
			$states = WC()->countries->get_states( $country );
			if ( is_array( $states ) && $states ) {
				return $states;
			}
		}
		return array();
	}

	private static function base_schemas() {
		return array(
			'CL' => array(
				array( 'key' => 'state', 'type' => 'select', 'required' => true, 'label' => __( 'Region', 'order-from-dm' ) ),
				array( 'key' => 'city', 'type' => 'select', 'required' => true, 'label' => __( 'Comuna', 'order-from-dm' ), 'localities' => true ),
				array( 'key' => 'postcode', 'type' => 'text', 'required' => false, 'label' => __( 'Postal code', 'order-from-dm' ) ),
			),
			'MX' => array(
				array( 'key' => 'state', 'type' => 'select', 'required' => true, 'label' => __( 'State', 'order-from-dm' ) ),
				array( 'key' => 'city', 'type' => 'text', 'required' => true, 'label' => __( 'City', 'order-from-dm' ) ),
				array( 'key' => 'postcode', 'type' => 'text', 'required' => true, 'label' => __( 'Postal code', 'order-from-dm' ) ),
			),
			'PE' => array(
				array( 'key' => 'state', 'type' => 'select', 'required' => true, 'label' => __( 'Department', 'order-from-dm' ) ),
				array( 'key' => 'city', 'type' => 'text', 'required' => true, 'label' => __( 'City / District', 'order-from-dm' ) ),
				array( 'key' => 'postcode', 'type' => 'text', 'required' => false, 'label' => __( 'Postal code', 'order-from-dm' ) ),
			),
			'CO' => array(
				array( 'key' => 'state', 'type' => 'select', 'required' => true, 'label' => __( 'Department', 'order-from-dm' ) ),
				array( 'key' => 'city', 'type' => 'text', 'required' => true, 'label' => __( 'City', 'order-from-dm' ) ),
				array( 'key' => 'postcode', 'type' => 'text', 'required' => true, 'label' => __( 'Postal code', 'order-from-dm' ) ),
			),
			'AR' => array(
				array( 'key' => 'state', 'type' => 'select', 'required' => true, 'label' => __( 'Province', 'order-from-dm' ) ),
				array( 'key' => 'city', 'type' => 'text', 'required' => true, 'label' => __( 'City', 'order-from-dm' ) ),
				array( 'key' => 'postcode', 'type' => 'text', 'required' => false, 'label' => __( 'Postal code', 'order-from-dm' ) ),
			),
			'BR' => array(
				array( 'key' => 'state', 'type' => 'select', 'required' => true, 'label' => __( 'State', 'order-from-dm' ) ),
				array( 'key' => 'city', 'type' => 'text', 'required' => true, 'label' => __( 'City', 'order-from-dm' ) ),
				array( 'key' => 'postcode', 'type' => 'text', 'required' => true, 'label' => __( 'Postal code', 'order-from-dm' ) ),
			),
			'ES' => array(
				array( 'key' => 'state', 'type' => 'select', 'required' => true, 'label' => __( 'Province', 'order-from-dm' ) ),
				array( 'key' => 'city', 'type' => 'text', 'required' => true, 'label' => __( 'City', 'order-from-dm' ) ),
				array( 'key' => 'postcode', 'type' => 'text', 'required' => true, 'label' => __( 'Postal code', 'order-from-dm' ) ),
			),
		);
	}

	public static function fields_for_country( $country ) {
		$country = self::sanitize_country( $country );
		$schema  = self::base_schemas()[ $country ] ?? self::base_schemas()['CL'];
		$states  = self::get_states_raw( $country );
		$out     = array();
		foreach ( $schema as $field ) {
			$f = $field;
			if ( 'state' === $f['key'] && ! $states ) {
				$f['type'] = 'text';
			}
			if ( 'city' === $f['key'] && empty( $f['localities'] ) ) {
				$f['type'] = 'text';
			}
			$out[] = $f;
		}
		return $out;
	}
}
