<?php
/**
 * Meta keys, defaults, merge/sanitize helpers.
 *
 * @package Image_Gallery_Custom_Post_Type
 */

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

/**
 * Post meta and global option helpers for galleries.
 */
class NZP_IGL_Storage {

	public const META_IDS  = '_nzp_igl_attachment_ids';
	public const META_OPTS = '_nzp_igl_display_options';
	public const OPTION_GLOBAL = 'nzp_igl_global_defaults';

	/**
	 * @return array<string,mixed>
	 */
	public static function default_options() {
		return array(
			'layout'          => 'grid',
			'accent_color'    => '',
			'title_color'     => '',
			'excerpt_color'   => '',
			'columns'         => 3,
			'card_radius'     => 8,
			'show_titles'     => 1,
			'show_captions'   => 1,
			'link_to_media'   => 1,
		);
	}

	/**
	 * @return array<string,mixed>
	 */
	public static function get_global_options() {
		$raw = get_option( self::OPTION_GLOBAL, array() );
		return self::sanitize_options( is_array( $raw ) ? $raw : array() );
	}

	/**
	 * Merged display options: global defaults + post overrides.
	 *
	 * @param int $post_id Gallery post ID.
	 * @return array<string,mixed>
	 */
	public static function get_merged_options( $post_id ) {
		$post_id = (int) $post_id;
		$base     = self::get_global_options();
		if ( $post_id <= 0 ) {
			return $base;
		}
		$meta = get_post_meta( $post_id, self::META_OPTS, true );
		if ( ! is_array( $meta ) ) {
			$meta = array();
		}
		return self::sanitize_options( array_merge( $base, $meta ) );
	}

	/**
	 * @param int $post_id Gallery post ID.
	 * @return int[]
	 */
	public static function get_image_ids( $post_id ) {
		$post_id = (int) $post_id;
		if ( $post_id <= 0 ) {
			return array();
		}
		$raw = get_post_meta( $post_id, self::META_IDS, true );
		if ( ! is_array( $raw ) ) {
			return array();
		}
		$out = array();
		foreach ( $raw as $id ) {
			$id = absint( $id );
			if ( $id > 0 ) {
				$out[] = $id;
			}
		}
		return array_values( array_unique( $out ) );
	}

	/**
	 * @param array<string,mixed> $in Raw options.
	 * @return array<string,mixed>
	 */
	public static function sanitize_options( array $in ) {
		$d = self::default_options();
		$out = array(
			'layout'        => isset( $in['layout'] ) ? sanitize_key( (string) $in['layout'] ) : $d['layout'],
			'accent_color'  => self::sanitize_hex_color_or_empty( isset( $in['accent_color'] ) ? (string) $in['accent_color'] : '' ),
			'title_color'   => self::sanitize_hex_color_or_empty( isset( $in['title_color'] ) ? (string) $in['title_color'] : '' ),
			'excerpt_color' => self::sanitize_hex_color_or_empty( isset( $in['excerpt_color'] ) ? (string) $in['excerpt_color'] : '' ),
			'columns'       => isset( $in['columns'] ) ? max( 1, min( 4, absint( $in['columns'] ) ) ) : $d['columns'],
			'card_radius'   => isset( $in['card_radius'] ) ? max( 0, min( 32, absint( $in['card_radius'] ) ) ) : $d['card_radius'],
			'show_titles'   => ! empty( $in['show_titles'] ) ? 1 : 0,
			'show_captions' => ! empty( $in['show_captions'] ) ? 1 : 0,
			'link_to_media' => ! empty( $in['link_to_media'] ) ? 1 : 0,
		);
		$layouts = array( 'listing', 'grid', 'mosaic', 'showcase', 'carousel' );
		if ( ! in_array( $out['layout'], $layouts, true ) ) {
			$out['layout'] = 'grid';
		}
		$out['layout'] = NZP_IGL_Limits::normalize_layout( (string) $out['layout'] );
		return $out;
	}

	/**
	 * @param string $c Candidate color.
	 * @return string Empty or #rrggbb lowercase.
	 */
	private static function sanitize_hex_color_or_empty( $c ) {
		$c = trim( (string) $c );
		if ( $c === '' ) {
			return '';
		}
		if ( function_exists( 'sanitize_hex_color' ) ) {
			$s = sanitize_hex_color( $c );
			return $s ? strtolower( $s ) : '';
		}
		return preg_match( '/^#([0-9a-f]{3}|[0-9a-f]{6})$/i', $c ) ? strtolower( $c ) : '';
	}

	/**
	 * @param array<int,int|string> $ids Attachment IDs.
	 * @return int[]
	 */
	public static function sanitize_image_ids( array $ids ) {
		$out = array();
		foreach ( $ids as $id ) {
			$id = absint( $id );
			if ( $id > 0 ) {
				$out[] = $id;
			}
			if ( count( $out ) >= NZP_IGL_Limits::max_gallery_images() ) {
				break;
			}
		}
		return array_values( array_unique( $out ) );
	}
}
