<?php

namespace Gigneo\Post_Meta;

use Carbon_Fields\Field\Field;
use Carbon_Fields\Datastore\Datastore;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Class Serialized
 *
 * Custom datastore for Carbon Fields using post meta.
 *
 * @since 0.0.1
 */
class Serialized extends Datastore {


	/**
	 * Initialize the datastore
	 */
	public function init() {
	}

	/**
	 * Load the field value(s)
	 *
	 * @param Field $field The field to load value(s) in.
	 *
	 * @return array|void
	 */
	public function load( Field $field ) {

		$post_id = $this->get_current_post_id();

		$key   = $this->get_key_for_field( $field );
		$value = get_post_meta( $post_id, $key );
		$value = $value[0] ?? $value;

		if ( is_a( $field, '\\Carbon_Fields\\Field\\Map_Field' ) ) {
			if ( ! is_array( $value ) || ! isset( $value['lat'], $value['lng'], $value['address'] ) ) {
				return array(
					'lat'     => gigneo_option( '_gigneo_ts_map_latitude', '29.4171886' ),
					'lng'     => gigneo_option( '_gigneo_ts_map_longitude', '-98.4923103' ),
					'zoom'    => gigneo_option( '_gigneo_ts_map_zoom', '10' ),
					'address' => '',
				);
			}
		}

		return $value;
	}

	protected function get_key_for_field( Field $field ) {
		$key = '_' . $field->get_base_name();

		return $key;
	}

	/**
	 * Save the field value(s)
	 *
	 * @param Field $field The field to save.
	 */
	public function save( Field $field ) {
		if ( ! empty( $field->get_hierarchy() ) ) {
			return; // only applicable to root fields
		}

		$post_id = $this->get_current_post_id();

		$key   = $this->get_key_for_field( $field );
		$value = $field->get_full_value();
		if ( is_a( $field, '\\Carbon_Fields\\Field\\Complex_Field' ) ) {
			$value = $this->sanitize_complex_field( $field->get_value_tree() );
		} elseif ( is_a( $field, '\\Carbon_Fields\\Field\\Multiselect_Field' ) ) {
			$value = $field->get_value();
		} elseif ( is_a( $field, '\\Carbon_Fields\\Field\\Media_Gallery_Field' ) ) {
			$value = $field->get_value();
		} elseif ( is_a( $field, '\\Carbon_Fields\\Field\\Map_Field' ) ) {
			$value = $field->get_value();
		}

		update_post_meta( $post_id, $key, $value );
	}

	/**
	 * Delete the field value(s)
	 *
	 * @param Field $field The field to delete.
	 */
	public function delete( Field $field ) {
		if ( ! empty( $field->get_hierarchy() ) ) {
			return; // only applicable to root fields
		}

		$post_id = $this->get_current_post_id();

		$key = $this->get_key_for_field( $field );
		delete_post_meta( $post_id, $key );
	}

	/**
	 * Sanitize and properly structure complex field values.
	 *
	 * @param mixed $data The complex field data.
	 *
	 * @return array
	 */
	protected function sanitize_complex_field( $data ) {
		if ( ! is_array( $data ) ) {
			return $data; // Return scalar values as is
		}

		$cleaned_data = array();

		foreach ( $data as $key => $value ) {
			if ( is_array( $value ) ) {
				if ( isset( $value[0] ) && is_array( $value[0] ) && ( isset( $value[0]['value'] ) || isset( $value[0]['item_value'] ) ) && count( $value[0] ) === 1 ) {
					$cleaned_data[ $key ] = $value[0]['value'] ?? $value[0]['item_value'];
				} elseif ( isset( $value[0] ) && is_array( $value[0] ) ) {
					$cleaned_data[ $key ] = array_map( array( $this, 'sanitize_complex_field' ), $value );
				} else {
					$cleaned_data[ $key ] = $this->sanitize_complex_field( $value );
				}
			} else {
				$cleaned_data[ $key ] = $value;
			}
		}

		return $cleaned_data;
	}

	/**
	 * Get the current post ID.
	 *
	 * @return int|null
	 */
	protected function get_current_post_id() {
		global $post;
		if ( isset( $post->ID ) ) {
			return $post->ID;
		}

		if ( is_admin() ) {
			$screen = get_current_screen();
			if ( isset( $screen->post_id ) ) {
				return $screen->post_id;
			}
		}

		return null;
	}
}
