<?php

namespace Gigneo\Term_Meta;

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

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

/**
 * Class Serialized
 *
 * Handles Carbon Fields term meta storage.
 *
 * @since 0.0.1
 */
class Serialized extends Datastore {

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

	/**
	 * Load the field value(s) for a term.
	 *
	 * @param Field $field The field to load values from.
	 *
	 * @return mixed
	 */
	public function load( Field $field ) {
		$term_id = $this->get_term_id();
		$key     = $this->get_key_for_field( $field );
		if ( $term_id ) {
			$value = get_term_meta( $term_id, $key, true );
			return $value ? $value : null;
		}

		return null;
	}

	/**
	 * Retrieve the current term ID from the request.
	 *
	 * @return int|null
	 */
	protected function get_term_id() {
		$taxonomy = get_taxonomy( 'gigneo_facet' );
		if ( ! $taxonomy || ! current_user_can( $taxonomy->cap->manage_terms ) ) {
			return null;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only parameters no nonce required.
		$tag_id = filter_input( INPUT_POST, 'tag_ID', FILTER_VALIDATE_INT );

		if ( ! $tag_id ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only parameters no nonce required.
			$tag_id = filter_input( INPUT_GET, 'tag_ID', FILTER_VALIDATE_INT );
		}

		return $tag_id ?? null;
	}

	/**
	 * Get the meta key for the field.
	 *
	 * @param Field $field The field instance.
	 *
	 * @return string
	 */
	protected function get_key_for_field( Field $field ) {
		return '_' . $field->get_base_name();
	}

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

		$term_id = $this->get_term_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();
		}

		if ( empty( $term_id ) ) {
			add_action(
				'created_gigneo_facet',
				function ( $term_id ) use ( &$key, &$value ) {
					update_term_meta( $term_id, $key, $value );
				},
				99
			);
		} else {
			update_term_meta( $term_id, $key, $value );
		}
	}

	/**
	 * 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'] ) && count( $value[0] ) === 1 ) {
					$cleaned_data[ $key ] = $value[0]['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;
	}

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

		$term_id = $this->get_term_id();
		$key     = $this->get_key_for_field( $field );

		if ( $term_id ) {
			delete_term_meta( $term_id, $key );
		}
	}
}