<?php
/**
 * Custom Fields admin list columns.
 *
 * @package CustomFields
 * @since 1.2.0
 */

namespace CustomFields;

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

/**
 * Adds optional post list columns for fields flagged with show_in_list.
 */
final class AdminColumns {

	private Locations $locations;

	public function __construct( Locations $locations ) {
		$this->locations = $locations;
	}

	/**
	 * Register hooks for every active post type.
	 */
	public function register(): void {
		foreach ( $this->locations->activePostTypes() as $post_type ) {
			add_filter( 'manage_' . $post_type . '_posts_columns', [ $this, 'addColumns' ] );
			add_action( 'manage_' . $post_type . '_posts_custom_column', [ $this, 'renderColumn' ], 10, 2 );
		}
	}

	/**
	 * @param array<string, string> $columns Existing columns.
	 * @return array<string, string>
	 */
	public function addColumns( array $columns ): array {
		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
		$post_type = $screen && isset( $screen->post_type ) ? (string) $screen->post_type : '';
		if ( $post_type === '' ) {
			return $columns;
		}

		foreach ( $this->listFieldsForPostType( $post_type ) as $meta_key => $field ) {
			$label = (string) ( $field['label'] ?? $meta_key );
			$columns[ 'wpps_cf_' . $meta_key ] = $label;
		}

		return $columns;
	}

	/**
	 * @param string $column  Column key.
	 * @param int    $post_id Post ID.
	 */
	public function renderColumn( string $column, int $post_id ): void {
		if ( ! str_starts_with( $column, 'wpps_cf_' ) ) {
			return;
		}

		$meta_key = substr( $column, 8 );
		$post_type = get_post_type( $post_id );
		if ( ! is_string( $post_type ) ) {
			return;
		}

		$field = $this->listFieldsForPostType( $post_type )[ $meta_key ] ?? null;
		if ( ! is_array( $field ) ) {
			return;
		}

		$value = get_post_meta( $post_id, $meta_key, true );
		echo esc_html( $this->formatListValue( $field, $value ) );
	}

	/**
	 * @param string $post_type Post type key.
	 * @return array<string, array<string, mixed>> meta_key => field
	 */
	private function listFieldsForPostType( string $post_type ): array {
		$out = [];
		foreach ( $this->locations->groupsForPost( 0, $post_type ) as $group ) {
			$group_key = (string) ( $group['key'] ?? '' );
			$fields = isset( $group['fields'] ) && is_array( $group['fields'] ) ? $group['fields'] : [];
			foreach ( $fields as $field ) {
				if ( ! is_array( $field ) || empty( $field['show_in_list'] ) ) {
					continue;
				}
				$meta_key = MetaKeys::resolve( $group_key, $field );
				if ( $meta_key !== '' ) {
					$out[ $meta_key ] = $field;
				}
			}
		}

		return $out;
	}

	/**
	 * @param array<string, mixed> $field Field definition.
	 * @param mixed                $value Stored value.
	 */
	private function formatListValue( array $field, mixed $value ): string {
		$type = (string) ( $field['type'] ?? 'text' );

		if ( $value === '' || $value === null || $value === [] ) {
			return '—';
		}

		if ( $type === 'toggle' ) {
			return (string) $value === '1' ? __( 'Yes', 'wp-powersuite' ) : __( 'No', 'wp-powersuite' );
		}

		if ( in_array( $type, [ 'image', 'file' ], true ) ) {
			$id = (int) $value;
			if ( $id <= 0 ) {
				return '—';
			}
			$title = get_the_title( $id );

			return $title !== '' ? $title : (string) $id;
		}

		if ( $type === 'gallery' && is_array( $value ) ) {
			return (string) count( $value );
		}

		if ( is_array( $value ) ) {
			if ( isset( $value['url'] ) ) {
				return (string) ( $value['url'] ?? '' );
			}

			return implode( ', ', array_map( 'strval', $value ) );
		}

		$text = wp_strip_all_tags( (string) $value );

		return mb_strlen( $text ) > 80 ? mb_substr( $text, 0, 77 ) . '…' : $text;
	}
}
