<?php

namespace MDCE;

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

class MetaBox {

	private const DATE_META   = '_mdce_expiration_date';
	private const ACTION_META = '_mdce_expiration_action';

	private PostTypes $post_types;

	public function __construct( PostTypes $post_types ) {
		$this->post_types = $post_types;
	}

	public function register(): void {
		add_action( 'add_meta_boxes',        [ $this, 'add_meta_boxes' ] );
		add_action( 'save_post',             [ $this, 'save' ], 10, 2 );
		add_action( 'rest_api_init',         [ $this, 'register_meta' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
	}

	public function add_meta_boxes(): void {
		foreach ( $this->post_types->get_supported() as $post_type ) {
			add_meta_box(
				'spe-expiration',
				__( 'Post Expiration', 'monkeydesign-content-expiry' ),
				[ $this, 'render' ],
				$post_type,
				'side',
				'default'
			);
		}
	}

	public function render( \WP_Post $post ): void {
		$timestamp         = (int) get_post_meta( $post->ID, self::DATE_META, true );
		$expiration_action = get_post_meta( $post->ID, self::ACTION_META, true ) ?: 'draft';
		$enabled           = $timestamp > 0;
		$date_value        = $timestamp ? wp_date( 'Y-m-d H:i', $timestamp ) : '';

		$expiry_category_ids = (array) get_post_meta( $post->ID, '_mdce_expiry_category_ids', true );
		$expiry_new_title    = (string) get_post_meta( $post->ID, '_mdce_expiry_new_title', true );
		$has_categories      = is_object_in_taxonomy( $post->post_type, 'category' );

		wp_nonce_field( 'spe_save_expiration', 'spe_nonce' );
		require MDCE_PLUGIN_DIR . 'admin/views/meta-box.php';
	}

	public function save( int $post_id, \WP_Post $post ): void {
		if ( ! isset( $_POST['spe_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['spe_nonce'] ) ), 'spe_save_expiration' ) ) {
			return;
		}
		if ( ! $this->can_save( $post_id, $post ) ) {
			return;
		}

		// Fires on every valid save so extensions (SitemapExclusion, SearchExclusion, etc.) can piggyback.
		do_action( 'mdce_meta_box_save', $post_id );

		$enabled = isset( $_POST['spe_enabled'] );
		$action  = sanitize_key( $_POST['spe_expiration_action'] ?? 'draft' );
		$date    = sanitize_text_field( wp_unslash( $_POST['spe_expiration_date'] ?? '' ) );

		if ( ! $enabled || '' === $date ) {
			$this->clear( $post_id );
			return;
		}

		$allowed = (array) apply_filters( 'mdce_allowed_actions', [ 'draft', 'trash', 'private', 'delete', 'category', 'title' ] );
		if ( ! in_array( $action, $allowed, true ) ) {
			$action = 'draft';
		}

		$timestamp = $this->local_to_timestamp( $date );
		if ( ! $timestamp || $timestamp <= time() ) {
			$this->clear( $post_id );
			return;
		}

		update_post_meta( $post_id, self::DATE_META,   $timestamp );
		update_post_meta( $post_id, self::ACTION_META, $action );

		if ( 'category' === $action ) {
			$cat_ids = array_filter( array_map( 'intval', (array) ( $_POST['spe_expiry_category_ids'] ?? [] ) ) );
			update_post_meta( $post_id, '_mdce_expiry_category_ids', $cat_ids );
		} else {
			delete_post_meta( $post_id, '_mdce_expiry_category_ids' );
		}

		if ( 'title' === $action ) {
			$new_title = sanitize_text_field( wp_unslash( $_POST['spe_expiry_new_title'] ?? '' ) );
			update_post_meta( $post_id, '_mdce_expiry_new_title', $new_title );
		} else {
			delete_post_meta( $post_id, '_mdce_expiry_new_title' );
		}

		do_action( 'mdce_expiration_saved', $post_id, $timestamp, $action );
	}

	private function clear( int $post_id ): void {
		delete_post_meta( $post_id, self::DATE_META );
		delete_post_meta( $post_id, self::ACTION_META );
		do_action( 'mdce_expiration_cleared', $post_id );
	}

	private function can_save( int $post_id, \WP_Post $post ): bool {
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return false;
		}
		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			return false;
		}
		if ( ! $this->post_types->is_supported( $post->post_type ) ) {
			return false;
		}
		return true;
	}

	private function local_to_timestamp( string $date ): int|false {
		$dt = \DateTime::createFromFormat( 'Y-m-d H:i', $date, wp_timezone() );
		if ( ! $dt ) {
			$dt = \DateTime::createFromFormat( 'Y-m-d\TH:i', $date, wp_timezone() );
		}
		return $dt ? $dt->getTimestamp() : false;
	}

	public function register_meta(): void {
		foreach ( $this->post_types->get_supported() as $post_type ) {
			register_post_meta( $post_type, self::DATE_META, [
				'show_in_rest'  => true,
				'single'        => true,
				'type'          => 'integer',
				'auth_callback' => fn() => current_user_can( 'edit_posts' ),
			] );
			register_post_meta( $post_type, self::ACTION_META, [
				'show_in_rest'  => true,
				'single'        => true,
				'type'          => 'string',
				'auth_callback' => fn() => current_user_can( 'edit_posts' ),
			] );
		}
	}

	public function enqueue_assets( string $hook ): void {
		if ( ! in_array( $hook, [ 'post.php', 'post-new.php' ], true ) ) {
			return;
		}
		$screen = get_current_screen();
		if ( ! $screen || ! $this->post_types->is_supported( $screen->post_type ) ) {
			return;
		}

		$vendor = MDCE_PLUGIN_URL . 'assets/vendor/flatpickr/';
		wp_enqueue_style( 'flatpickr',  $vendor . 'flatpickr.min.css', [], '4.6.13' );
		wp_enqueue_script( 'flatpickr', $vendor . 'flatpickr.min.js', [], '4.6.13', true );

		wp_enqueue_style( 'mdce-admin',  MDCE_PLUGIN_URL . 'assets/css/admin.css', [ 'flatpickr' ], MDCE_VERSION );
		wp_enqueue_script( 'mdce-admin', MDCE_PLUGIN_URL . 'assets/js/admin.js', [ 'flatpickr' ], MDCE_VERSION, true );

		wp_add_inline_script( 'mdce-admin', '( function () {
			var sel = document.getElementById( "spe_expiration_action" );
			if ( ! sel ) return;
			var catWrap   = document.getElementById( "spe-category-wrap" );
			var titleWrap = document.getElementById( "spe-title-wrap" );
			sel.addEventListener( "change", function () {
				if ( catWrap )   catWrap.style.display   = this.value === "category" ? "" : "none";
				if ( titleWrap ) titleWrap.style.display  = this.value === "title"    ? "" : "none";
			} );
		}() );' );
	}
}
