<?php

/**
 * NavigationHandler — Domain handler for menus and theme switching.
 *
 * Owns: get_menus, manage_menus, switch_theme
 *
 * @package LolaCore\Actions\Handlers
 * @license GPL-2.0-or-later
 */

declare( strict_types=1 );

namespace LolaCore\Actions\Handlers;

use LolaCore\Actions\Contracts\ActionHandlerInterface;

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

class NavigationHandler implements ActionHandlerInterface {

	public function getSupportedActions(): array {
		return array( 'get_menus', 'manage_menus', 'switch_theme' );
	}

	public function handle( string $actionId, array $params, bool $dryRun ): array {
		return match ( $actionId ) {
			'get_menus'    => $this->getMenus( $params ),
			'manage_menus' => $this->manageMenus( $params, $dryRun ),
			'switch_theme' => $this->switchTheme( $params, $dryRun ),
			default        => throw new \Exception( esc_html( "NavigationHandler: unknown action '{$actionId}'." ) ),
		};
	}

	private function getMenus( array $params ): array {
		$menu_id = isset( $params['menu_id'] ) ? (int) $params['menu_id'] : 0;

		if ( $menu_id > 0 ) {
			$menu = wp_get_nav_menu_object( $menu_id );
			if ( ! $menu ) {
				throw new \Exception( esc_html( "Menu with ID {$menu_id} not found." ) );
			}
			$items     = wp_get_nav_menu_items( $menu_id );
			$item_data = array();
			if ( $items ) {
				foreach ( $items as $item ) {
					$item_data[] = array(
						'id'        => $item->ID,
						'title'     => $item->title,
						'url'       => $item->url,
						'type'      => $item->type,
						'object'    => $item->object,
						'object_id' => (int) $item->object_id,
						'parent'    => (int) $item->menu_item_parent,
						'order'     => (int) $item->menu_order,
					);
				}
			}
			return array( 'menu_id' => $menu->term_id, 'menu_name' => $menu->name, 'count' => $menu->count, 'items' => $item_data );
		}

		$menus     = wp_get_nav_menus();
		$locations = get_nav_menu_locations();
		$loc_names = get_registered_nav_menus();
		$data      = array();
		foreach ( $menus as $menu ) {
			$assigned = array();
			foreach ( $locations as $loc_slug => $loc_menu_id ) {
				if ( $loc_menu_id === $menu->term_id ) {
					$assigned[] = $loc_names[ $loc_slug ] ?? $loc_slug;
				}
			}
			$data[] = array( 'id' => $menu->term_id, 'name' => $menu->name, 'count' => $menu->count, 'locations' => $assigned );
		}
		return array( 'menus' => $data, 'total' => count( $data ) );
	}

	private function manageMenus( array $params, bool $dryRun ): array {
		$action = $params['action'] ?? '';
		if ( ! in_array( $action, array( 'create_menu', 'add_item', 'remove_item' ), true ) ) {
			throw new \Exception( "Invalid action. Use 'create_menu', 'add_item', or 'remove_item'." );
		}

		if ( $action === 'create_menu' ) {
			$menu_name = $params['menu_name'] ?? '';
			if ( empty( $menu_name ) ) {
				throw new \Exception( 'menu_name is required to create a menu.' );
			}
			if ( $dryRun ) {
				return array( 'action' => 'Will create navigation menu', 'menu_name' => $menu_name );
			}
			$menu_id = wp_create_nav_menu( sanitize_text_field( $menu_name ) );
			if ( is_wp_error( $menu_id ) ) {
				throw new \Exception( esc_html( $menu_id->get_error_message() ) );
			}
			return array( 'success' => true, 'menu_id' => $menu_id, 'message' => "Menu '{$menu_name}' created." );
		}

		if ( $action === 'add_item' ) {
			$menu_id     = (int) ( $params['menu_id'] ?? 0 );
			$item_title  = $params['item_title'] ?? '';
			$item_url    = $params['item_url'] ?? '';
			$item_object = $params['item_object'] ?? 'custom';
			$object_id   = (int) ( $params['item_object_id'] ?? 0 );
			$parent_id   = (int) ( $params['parent_item_id'] ?? 0 );

			if ( $menu_id <= 0 ) {
				throw new \Exception( 'menu_id is required to add items.' );
			}
			if ( empty( $item_title ) ) {
				throw new \Exception( 'item_title is required.' );
			}
			if ( $dryRun ) {
				return array( 'action' => 'Will add item to menu', 'menu_id' => $menu_id, 'item_title' => $item_title, 'item_type' => $item_object );
			}

			$menu_item_data = array(
				'menu-item-title'     => sanitize_text_field( $item_title ),
				'menu-item-status'    => 'publish',
				'menu-item-parent-id' => $parent_id,
			);
			if ( $item_object === 'custom' ) {
				$menu_item_data['menu-item-type'] = 'custom';
				$menu_item_data['menu-item-url']  = esc_url_raw( $item_url );
			} else {
				$type_map = array( 'page' => 'post_type', 'post' => 'post_type', 'category' => 'taxonomy' );
				$menu_item_data['menu-item-type']      = $type_map[ $item_object ] ?? 'post_type';
				$menu_item_data['menu-item-object']    = $item_object === 'category' ? 'category' : $item_object;
				$menu_item_data['menu-item-object-id'] = $object_id;
			}

			$result = wp_update_nav_menu_item( $menu_id, 0, $menu_item_data );
			if ( is_wp_error( $result ) ) {
				throw new \Exception( esc_html( $result->get_error_message() ) );
			}
			return array( 'success' => true, 'menu_item_id' => $result, 'message' => "Item '{$item_title}' added to menu." );
		}

		// remove_item
		$item_id = (int) ( $params['item_id'] ?? 0 );
		if ( $item_id <= 0 ) {
			throw new \Exception( 'item_id is required to remove a menu item.' );
		}
		$post = get_post( $item_id );
		if ( ! $post || $post->post_type !== 'nav_menu_item' ) {
			throw new \Exception( esc_html( "Menu item ID {$item_id} not found." ) );
		}
		if ( $dryRun ) {
			return array( 'action' => 'Will remove menu item', 'item_id' => $item_id, 'item_title' => $post->post_title );
		}
		$result = wp_delete_post( $item_id, true );
		return array( 'success' => (bool) $result, 'message' => $result ? "Menu item ID {$item_id} removed." : 'Failed to remove menu item.' );
	}

	private function switchTheme( array $params, bool $dryRun ): array {
		$stylesheet = $params['stylesheet'] ?? '';
		if ( empty( $stylesheet ) ) {
			throw new \Exception( 'stylesheet (theme directory name) is required.' );
		}
		$target = wp_get_theme( $stylesheet );
		if ( ! $target->exists() ) {
			// phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
			throw new \Exception( "Theme '{$stylesheet}' is not installed." );
		}
		$current = wp_get_theme();
		if ( $current->get_stylesheet() === $stylesheet ) {
			return array( 'success' => true, 'message' => "Theme '{$stylesheet}' is already active." );
		}
		if ( $dryRun ) {
			return array(
				'action'        => 'Will switch active theme',
				'current_theme' => $current->get( 'Name' ),
				'new_theme'     => $target->get( 'Name' ),
				'new_version'   => $target->get( 'Version' ),
				'warning'       => 'Switching themes may cause loss of theme-specific widgets, menus, and customizer settings. Ensure you have a backup.',
			);
		}
		switch_theme( $stylesheet );
		$now_active = wp_get_theme();
		$success    = $now_active->get_stylesheet() === $stylesheet;
		return array(
			'success'        => $success,
			'previous_theme' => $current->get( 'Name' ),
			'new_theme'      => $now_active->get( 'Name' ),
			'message'        => $success ? "Theme switched to '{$target->get( 'Name' )}'." : 'Theme switch failed.',
		);
	}
}
