<?php

/**
 * Registers the 'Model Texture' Custom Post Type and its metaboxes.
 *
 * @package ProductCustomizer
 */
// Exit if accessed directly.
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
/**
 * Register the 'Model Texture' Custom Post Type.
 */
function dprcu_textures_cpt_init() {
    $labels = array(
        'name'               => _x( 'Model Textures', 'post type general name', '3d-product-customizer' ),
        'singular_name'      => _x( 'Model Texture', 'post type singular name', '3d-product-customizer' ),
        'menu_name'          => _x( 'Model Textures', 'admin menu', '3d-product-customizer' ),
        'not_found'          => __( 'No model textures found.', '3d-product-customizer' ),
        'not_found_in_trash' => __( 'No model textures found in Trash.', '3d-product-customizer' ),
    );
    $args = array(
        'labels'             => $labels,
        'public'             => false,
        'publicly_queryable' => false,
        'show_ui'            => true,
        'show_in_menu'       => 'dprcu-settings',
        'query_var'          => false,
        'rewrite'            => false,
        'capability_type'    => 'post',
        'has_archive'        => false,
        'hierarchical'       => false,
        'menu_position'      => 20,
        'menu_icon'          => 'dashicons-format-image',
        'supports'           => array('title', 'thumbnail'),
        'show_in_rest'       => true,
    );
    register_post_type( 'dprcu_model_texture', $args );
}

add_action( 'init', 'dprcu_textures_cpt_init' );
/**
 * Register the 'Texture Category' taxonomy for Model Textures.
 */
function dprcu_textures_taxonomy_init() {
    $labels = array(
        'name'              => _x( 'Texture Categories', 'taxonomy general name', '3d-product-customizer' ),
        'singular_name'     => _x( 'Texture Category', 'taxonomy singular name', '3d-product-customizer' ),
        'search_items'      => __( 'Search Texture Categories', '3d-product-customizer' ),
        'all_items'         => __( 'All Texture Categories', '3d-product-customizer' ),
        'parent_item'       => __( 'Parent Category', '3d-product-customizer' ),
        'parent_item_colon' => __( 'Parent Category:', '3d-product-customizer' ),
        'edit_item'         => __( 'Edit Texture Category', '3d-product-customizer' ),
        'update_item'       => __( 'Update Texture Category', '3d-product-customizer' ),
        'add_new_item'      => __( 'Add New Texture Category', '3d-product-customizer' ),
        'new_item_name'     => __( 'New Texture Category Name', '3d-product-customizer' ),
        'menu_name'         => __( 'Categories', '3d-product-customizer' ),
    );
    register_taxonomy( 'dprcu_texture_category', 'dprcu_model_texture', array(
        'labels'            => $labels,
        'hierarchical'      => true,
        'show_ui'           => true,
        'show_in_menu'      => true,
        'show_in_rest'      => true,
        'show_admin_column' => true,
        'rewrite'           => false,
        'query_var'         => false,
    ) );
}

add_action( 'init', 'dprcu_textures_taxonomy_init' );
/**
 * Add the Texture Categories submenu under the plugin's custom menu.
 *
 * WordPress only auto-adds taxonomy submenus for CPTs with their own
 * top-level menu entry. Since dprcu_model_texture uses show_in_menu pointing
 * to 'dprcu-settings', the submenu must be registered manually.
 */
function dprcu_textures_taxonomy_submenu() {
    add_submenu_page(
        'dprcu-settings',
        __( 'Texture Categories', '3d-product-customizer' ),
        __( 'Texture Categories', '3d-product-customizer' ),
        'manage_options',
        'edit-tags.php?taxonomy=dprcu_texture_category&post_type=dprcu_model_texture'
    );
}

add_action( 'admin_menu', 'dprcu_textures_taxonomy_submenu' );
/**
 * Highlight the parent and submenu items when viewing dprcu_texture_category taxonomy.
 *
 * WordPress doesn't auto-highlight the parent menu for taxonomy edit pages,
 * so we manually set both parent_file and submenu_file to ensure proper menu highlighting.
 */
function dprcu_highlight_taxonomy_menu(  $parent_file  ) {
    global $pagenow, $submenu_file;
    if ( 'edit-tags.php' === $pagenow ) {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only context check for menu highlighting, no form processing
        $taxonomy = ( isset( $_GET['taxonomy'] ) ? sanitize_key( wp_unslash( $_GET['taxonomy'] ) ) : '' );
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only context check for menu highlighting, no form processing
        $post_type = ( isset( $_GET['post_type'] ) ? sanitize_key( wp_unslash( $_GET['post_type'] ) ) : '' );
        if ( 'dprcu_texture_category' === $taxonomy && 'dprcu_model_texture' === $post_type ) {
            $parent_file = 'dprcu-settings';
            $submenu_file = 'edit-tags.php?taxonomy=dprcu_texture_category&post_type=dprcu_model_texture';
        }
    }
    return $parent_file;
}

add_filter( 'parent_file', 'dprcu_highlight_taxonomy_menu' );
/**
 * Add a Texture Category filter dropdown to the dprcu_model_texture list table.
 */
function dprcu_textures_category_filter_dropdown(  $post_type  ) {
    if ( 'dprcu_model_texture' !== $post_type ) {
        return;
    }
    $terms = get_terms( array(
        'taxonomy'   => 'dprcu_texture_category',
        'hide_empty' => false,
    ) );
    if ( empty( $terms ) || is_wp_error( $terms ) ) {
        return;
    }
    // Check nonce for security
    $selected = '';
    if ( isset( $_GET['dprcu_texture_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['dprcu_texture_nonce'] ) ), 'dprcu_texture_filter' ) ) {
        $selected = ( isset( $_GET['dprcu_texture_category'] ) ? sanitize_key( wp_unslash( $_GET['dprcu_texture_category'] ) ) : '' );
    }
    ?>
	<?php 
    wp_nonce_field( 'dprcu_texture_filter', 'dprcu_texture_nonce', false );
    ?>
	<select name="dprcu_texture_category">
		<option value=""><?php 
    esc_html_e( 'All Categories', '3d-product-customizer' );
    ?></option>
		<?php 
    foreach ( $terms as $term ) {
        ?>
			<option value="<?php 
        echo esc_attr( $term->slug );
        ?>" <?php 
        selected( $selected, $term->slug );
        ?>>
				<?php 
        echo esc_html( $term->name );
        ?>
			</option>
		<?php 
    }
    ?>
	</select>
	<?php 
}

add_action( 'restrict_manage_posts', 'dprcu_textures_category_filter_dropdown' );
/**
 * Apply the dprcu_texture_category filter to the list table query.
 */
function dprcu_textures_category_filter_query(  $query  ) {
    if ( !is_admin() || !$query->is_main_query() ) {
        return;
    }
    if ( 'dprcu_model_texture' !== $query->get( 'post_type' ) ) {
        return;
    }
    // Check nonce for security
    if ( !isset( $_GET['dprcu_texture_nonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['dprcu_texture_nonce'] ) ), 'dprcu_texture_filter' ) ) {
        return;
    }
    $cat = ( isset( $_GET['dprcu_texture_category'] ) ? sanitize_key( wp_unslash( $_GET['dprcu_texture_category'] ) ) : '' );
    if ( empty( $cat ) ) {
        return;
    }
    $query->set( 'tax_query', array(array(
        'taxonomy' => 'dprcu_texture_category',
        'field'    => 'slug',
        'terms'    => $cat,
    )) );
}

add_action( 'parse_query', 'dprcu_textures_category_filter_query' );
/**
 * Add the custom metabox for optional texture maps.
 */
function dprcu_textures_add_metaboxes() {
    add_meta_box(
        'dprcu_texture_maps',
        'Optional Texture Maps',
        'dprcu_textures_metabox_html',
        'dprcu_model_texture',
        'normal',
        'default'
    );
    if ( dprcu_fs()?->can_use_premium_code__premium_only() ) {
        add_meta_box(
            'dprcu_texture_preview',
            __( 'Material Preview', '3d-product-customizer' ),
            'dprcu_textures_preview_metabox_html__premium_only',
            'dprcu_model_texture',
            'side',
            'high'
        );
    } else {
        add_meta_box(
            'dprcu_texture_preview',
            __( 'Material Preview', '3d-product-customizer' ),
            'dprcu_textures_preview_metabox_html_free',
            'dprcu_model_texture',
            'side',
            'high'
        );
    }
    add_meta_box(
        'dprcu_texture_color_swatch',
        __( 'Color Swatch', '3d-product-customizer' ),
        'dprcu_textures_color_swatch_metabox_html',
        'dprcu_model_texture',
        'side',
        'default'
    );
}

add_action( 'add_meta_boxes', 'dprcu_textures_add_metaboxes' );
/**
 * Render the Material Preview metabox (free — upsell).
 */
function dprcu_textures_preview_metabox_html_free() {
    $upgrade_url = dprcu_fs()->get_upgrade_url();
    ?>
	<a class="material-preview-notice" href="<?php 
    echo esc_url( $upgrade_url );
    ?>" target="_blank">
		<span><?php 
    esc_html_e( 'Material Preview', '3d-product-customizer' );
    ?></span>
		<span class="notice-btn"><?php 
    esc_html_e( 'Upgrade to Premium', '3d-product-customizer' );
    ?></span>
	</a>
	<?php 
}

/**
 * Render the Color Swatch metabox.
 */
function dprcu_textures_color_swatch_metabox_html(  $post  ) {
    $color = ( get_post_meta( $post->ID, '_dprcu_texture_color', true ) ?: '' );
    ?>
	<p class="description">
		<?php 
    esc_html_e( 'Used as a fast-loading fallback when no base color image is set.', '3d-product-customizer' );
    ?>
	</p>
	<div style="margin-top: 10px;">
		<input type="text" name="dprcu_texture_color" id="dprcu_texture_color" value="<?php 
    echo esc_attr( $color );
    ?>"
			class="psc-color-picker" data-default-color="">
	</div>
	<?php 
}

/**
 * Render the HTML for the metabox.
 */
function dprcu_textures_metabox_html(  $post  ) {
    wp_nonce_field( 'dprcu_textures_save', 'dprcu_textures_nonce' );
    $roughness_id = get_post_meta( $post->ID, '_dprcu_texture_roughness_id', true );
    $normal_id = get_post_meta( $post->ID, '_dprcu_texture_normal_id', true );
    $roughness_url = ( $roughness_id ? wp_get_attachment_image_url( $roughness_id, 'thumbnail' ) : '' );
    $normal_url = ( $normal_id ? wp_get_attachment_image_url( $normal_id, 'thumbnail' ) : '' );
    // Slider values
    $roughness = get_post_meta( $post->ID, '_dprcu_texture_roughness', true );
    if ( '' === $roughness ) {
        $roughness = '0.5';
        // Default
    }
    $metalness = get_post_meta( $post->ID, '_dprcu_texture_metalness', true );
    if ( '' === $metalness ) {
        $metalness = '0.0';
        // Default Plastic
    }
    $env_intensity = get_post_meta( $post->ID, '_dprcu_texture_env_intensity', true );
    if ( '' === $env_intensity ) {
        $env_intensity = '1.0';
        // Default
    }
    $disp_scale = get_post_meta( $post->ID, '_dprcu_texture_disp_scale', true );
    if ( '' === $disp_scale ) {
        $disp_scale = '0.01';
        // Default
    }
    ?>

	<h3><?php 
    esc_html_e( 'Material Properties', '3d-product-customizer' );
    ?></h3>
	<p class="description">
		<?php 
    esc_html_e( 'Fine-tune how light interacts with this material.', '3d-product-customizer' );
    ?>
	</p>

	<div class="texture-field-container">
		<div class="texture-field-wrapper" style="margin-bottom: 15px;">
			<label><strong><?php 
    esc_html_e( 'Roughness', '3d-product-customizer' );
    ?></strong>
				<?php 
    esc_html_e( '(0 = Mirror, 1 = Matte)', '3d-product-customizer' );
    ?></label><br>
			<div style="display:flex; align-items:center; gap:10px;">
				<input type="range" min="0" max="1" step="0.01" value="<?php 
    echo esc_attr( $roughness );
    ?>"
					data-slider="roughness" style="width:200px;">
				<input type="number" step="0.01" name="dprcu_texture_roughness" id="dprcu_texture_roughness"
					value="<?php 
    echo esc_attr( $roughness );
    ?>" style="width:60px;">
			</div>

			<label><strong><?php 
    esc_html_e( 'Metalness', '3d-product-customizer' );
    ?></strong>
				<?php 
    esc_html_e( '(0 = Plastic, 1 = Metal)', '3d-product-customizer' );
    ?></label><br>
			<div style="display:flex; align-items:center; gap:10px;">
				<input type="range" min="0" max="1" step="0.01" value="<?php 
    echo esc_attr( $metalness );
    ?>"
					data-slider="metalness" style="width:200px;">
				<input type="number" step="0.01" name="dprcu_texture_metalness" id="dprcu_texture_metalness"
					value="<?php 
    echo esc_attr( $metalness );
    ?>" style="width:60px;">
			</div>
		</div>

		<?php 
    if ( dprcu_fs()?->can_use_premium_code__premium_only() ) {
        ?>
			<?php 
        // Prepare data for advanced material rendering
        $data = array(
            'roughness_id'  => $roughness_id,
            'roughness_url' => $roughness_url,
            'normal_id'     => $normal_id,
            'normal_url'    => $normal_url,
            'env_intensity' => $env_intensity,
            'disp_scale'    => $disp_scale,
        );
        dprcu_textures_render_advanced_material__premium_only( $post, $data );
        ?>

		<?php 
    } else {
        ?>

			<?php 
        dprcu_premium_notice( array(
            'title'            => __( 'Advanced Material Controls', '3d-product-customizer' ),
            'free_features'    => array(
                __( 'Upload 3D model (.glb / .gltf)', '3d-product-customizer' ),
                __( 'Base color texture per material', '3d-product-customizer' ),
                __( 'Roughness & metalness value sliders', '3d-product-customizer' ),
                __( 'Customization steps (1 texture per option)', '3d-product-customizer' ),
                __( 'Viewer Only Mode (model in product gallery)', '3d-product-customizer' ),
                __( 'Camera, background & zoom settings', '3d-product-customizer' ),
                __( 'HDR environment map support', '3d-product-customizer' )
            ),
            'premium_features' => array(
                __( 'Multiple textures per option', '3d-product-customizer' ),
                __( 'Bulk Add Materials per step', '3d-product-customizer' ),
                __( 'Show / Hide mesh controls per option', '3d-product-customizer' ),
                __( 'Roughness Map texture', '3d-product-customizer' ),
                __( 'Normal Map texture', '3d-product-customizer' ),
                __( 'Ambient Occlusion (AO) Map', '3d-product-customizer' ),
                __( 'Metalness Map texture', '3d-product-customizer' ),
                __( 'Displacement Map texture', '3d-product-customizer' ),
                __( 'Reflection Intensity control', '3d-product-customizer' ),
                __( 'Displacement Scale control', '3d-product-customizer' )
            ),
        ) );
    }
    ?>

	</div>

	<?php 
}

/**
 * Save the custom meta data.
 */
function dprcu_textures_save_postdata(  $post_id  ) {
    // Check security nonce
    if ( !isset( $_POST['dprcu_textures_nonce'] ) || !wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['dprcu_textures_nonce'] ) ), 'dprcu_textures_save' ) ) {
        return;
    }
    // Check for autosave
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }
    // Check user permissions
    if ( !current_user_can( 'edit_post', $post_id ) ) {
        return;
    }
    // Make sure we are saving the correct post type
    if ( !isset( $_POST['post_type'] ) || 'dprcu_model_texture' !== sanitize_key( wp_unslash( $_POST['post_type'] ) ) ) {
        return;
    }
    // --- Helper function to attach images ---
    // This sets the post_parent for an attachment ID.
    $attach_image = function ( $attachment_id, $post_id ) {
        if ( !empty( $attachment_id ) ) {
            // Get the attachment post
            $attachment_post = get_post( $attachment_id );
            // Only update if it's not already attached to this post
            if ( $attachment_post && $attachment_post->post_parent !== $post_id ) {
                // Update the attachment's parent
                wp_update_post( array(
                    'ID'          => $attachment_id,
                    'post_parent' => $post_id,
                ) );
            }
        }
    };
    // ------------------------------------
    // Save Roughness ID and attach it.
    // absint() is correct here — attachment IDs are always positive integers.
    if ( isset( $_POST['dprcu_texture_roughness_id'] ) ) {
        $roughness_id = absint( wp_unslash( $_POST['dprcu_texture_roughness_id'] ) );
        update_post_meta( $post_id, '_dprcu_texture_roughness_id', $roughness_id );
        $attach_image( $roughness_id, $post_id );
    }
    // Save Normal ID and attach it.
    if ( isset( $_POST['dprcu_texture_normal_id'] ) ) {
        $normal_id = absint( wp_unslash( $_POST['dprcu_texture_normal_id'] ) );
        update_post_meta( $post_id, '_dprcu_texture_normal_id', $normal_id );
        $attach_image( $normal_id, $post_id );
    }
    // Save AO ID and attach it.
    if ( isset( $_POST['dprcu_texture_ao_id'] ) ) {
        $ao_id = absint( wp_unslash( $_POST['dprcu_texture_ao_id'] ) );
        update_post_meta( $post_id, '_dprcu_texture_ao_id', $ao_id );
        $attach_image( $ao_id, $post_id );
    }
    // Save Metalness ID and attach it.
    if ( isset( $_POST['dprcu_texture_metalness_id'] ) ) {
        $metalness_id = absint( wp_unslash( $_POST['dprcu_texture_metalness_id'] ) );
        update_post_meta( $post_id, '_dprcu_texture_metalness_id', $metalness_id );
        $attach_image( $metalness_id, $post_id );
    }
    // Save Displacement ID and attach it.
    if ( isset( $_POST['dprcu_texture_displacement_id'] ) ) {
        $displacement_id = absint( wp_unslash( $_POST['dprcu_texture_displacement_id'] ) );
        update_post_meta( $post_id, '_dprcu_texture_displacement_id', $displacement_id );
        $attach_image( $displacement_id, $post_id );
    }
    if ( isset( $_POST['dprcu_texture_roughness'] ) ) {
        update_post_meta( $post_id, '_dprcu_texture_roughness', floatval( wp_unslash( $_POST['dprcu_texture_roughness'] ) ) );
    }
    if ( isset( $_POST['dprcu_texture_metalness'] ) ) {
        update_post_meta( $post_id, '_dprcu_texture_metalness', floatval( wp_unslash( $_POST['dprcu_texture_metalness'] ) ) );
    }
    if ( isset( $_POST['dprcu_texture_env_intensity'] ) ) {
        update_post_meta( $post_id, '_dprcu_texture_env_intensity', floatval( wp_unslash( $_POST['dprcu_texture_env_intensity'] ) ) );
    }
    if ( isset( $_POST['dprcu_texture_disp_scale'] ) ) {
        update_post_meta( $post_id, '_dprcu_texture_disp_scale', floatval( wp_unslash( $_POST['dprcu_texture_disp_scale'] ) ) );
    }
    if ( isset( $_POST['dprcu_texture_color'] ) ) {
        $color = sanitize_hex_color( wp_unslash( $_POST['dprcu_texture_color'] ) );
        update_post_meta( $post_id, '_dprcu_texture_color', ( $color ? $color : '' ) );
    }
}

add_action( 'save_post', 'dprcu_textures_save_postdata' );
/**
 * Add admin columns for 'baseColor' and re-order.
 */
function dprcu_admin_columns(  $columns  ) {
    $new_columns = array();
    $new_columns['cb'] = $columns['cb'];
    // Checkbox
    $new_columns['base_color'] = __( 'Base Color', '3d-product-customizer' );
    // Custom column
    $new_columns['title'] = $columns['title'];
    // Title
    $new_columns['date'] = $columns['date'];
    // Date
    return $new_columns;
}

add_filter( 'manage_dprcu_model_texture_posts_columns', 'dprcu_admin_columns' );
/**
 * Display content for the custom 'base_color' column.
 */
function dprcu_custom_column_content(  $column, $post_id  ) {
    if ( 'base_color' === $column ) {
        if ( has_post_thumbnail( $post_id ) ) {
            echo get_the_post_thumbnail( $post_id, array(80, 80) );
        } else {
            $color = get_post_meta( $post_id, '_dprcu_texture_color', true );
            if ( $color ) {
                echo '<div class="grid-color-swatch" style="background:' . esc_attr( $color ) . ';"><span>' . esc_html__( 'HEX', '3d-product-customizer' ) . '</span></div>';
            } else {
                echo esc_html__( '—', '3d-product-customizer' );
            }
        }
    }
}

add_action(
    'manage_dprcu_model_texture_posts_custom_column',
    'dprcu_custom_column_content',
    10,
    2
);
/**
 * Enqueue admin CSS for the grid view.
 */
function dprcu_admin_grid_styles(  $hook  ) {
    global $post_type;
    if ( 'edit.php' === $hook && 'dprcu_model_texture' === $post_type || 'dprcu_model_texture' === get_post_type() && in_array( $hook, array('post-new.php', 'post.php'), true ) ) {
        wp_enqueue_style(
            'dprcu-textures-grid-view',
            plugin_dir_url( __FILE__ ) . 'admin/css/textures-grid.css',
            array(),
            '1.0'
        );
    }
}

add_action( 'admin_enqueue_scripts', 'dprcu_admin_grid_styles' );
/**
 * Hide 'dprcu_model_texture'Featured Images from the main Media Library.
 *
 * This function modifies the main WordPress media query to exclude any
 * image that is "attached" (i.e., set as a Featured Image) to a
 * 'dprcu_model_texture' post.
 */
function dprcu_hide_from_media_library(  $query  ) {
    // 1. Only run in the admin area.
    if ( !is_admin() ) {
        return;
    }
    $is_media_library_grid = false;
    // 2. Safely check for the main grid screen.
    // get_current_screen() is not available on AJAX requests,
    // so we must check if the function exists first.
    if ( function_exists( 'get_current_screen' ) ) {
        $screen = get_current_screen();
        $is_media_library_grid = $screen && 'upload' === $screen->id && $query->is_main_query();
    }
    // 3. Check for the "Add Media" modal (which is an AJAX query).
    $is_media_library_modal = 'query-attachments' === $query->get( 'action' );
    // 4. If we are on either screen, apply the filter.
    if ( $is_media_library_grid || $is_media_library_modal ) {
        // Get all post IDs from your Model Textures CPT
        $texture_post_ids = get_posts( array(
            'post_type'      => 'dprcu_model_texture',
            'posts_per_page' => -1,
            'fields'         => 'ids',
            'post_status'    => 'any',
        ) );
        if ( !empty( $texture_post_ids ) ) {
            // Tell the query to *exclude* any attachment whose parent
            // is one of our model_texture posts.
            $query->set( 'post_parent__not_in', $texture_post_ids );
        }
    }
}

add_action( 'pre_get_posts', 'dprcu_hide_from_media_library' );