<?php
/**
 * Admin menu, pages, and Settings API handler.
 *
 * @package MerchantKits\AttendanceManager
 */

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

/**
 * Builds the admin menu structure and registers all settings.
 */
class MKAM_Admin {

	/**
	 * Settings page slug.
	 *
	 * @var string
	 */
	const MENU_SLUG = 'mkam-dashboard';

	/**
	 * Settings tabs and their setting definitions.
	 *
	 * @var array
	 */
	private $tabs = array();

	/**
	 * Hook admin actions.
	 */
	public function __construct() {
		add_action( 'admin_menu', array( $this, 'register_menu' ) );
		add_action( 'admin_init', array( $this, 'register_settings' ) );
		add_action( 'admin_init', array( $this, 'handle_row_actions' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
		add_action( 'admin_post_mkam_save_employee', array( $this, 'handle_save_employee' ) );
		add_action( 'admin_notices', array( $this, 'maybe_show_notice' ) );
	}

	/**
	 * Register the top-level menu and submenus.
	 *
	 * @return void
	 */
	public function register_menu() {
		$cap = MKAM_Core::admin_capability();

		add_menu_page(
			__( 'Attendance Manager', 'merchantkits-attendance-manager' ),
			__( 'Attendance', 'merchantkits-attendance-manager' ),
			$cap,
			self::MENU_SLUG,
			array( $this, 'render_dashboard' ),
			'dashicons-clock',
			30
		);

		$pages = array(
			array( 'mkam-dashboard', __( 'Dashboard', 'merchantkits-attendance-manager' ), 'render_dashboard' ),
			array( 'mkam-employees', __( 'Employees', 'merchantkits-attendance-manager' ), 'render_employees' ),
			array( 'mkam-attendance', __( 'Attendance', 'merchantkits-attendance-manager' ), 'render_attendance' ),
			array( 'mkam-leaves', __( 'Leaves', 'merchantkits-attendance-manager' ), 'render_leaves' ),
			array( 'mkam-shifts', __( 'Shifts', 'merchantkits-attendance-manager' ), 'render_shifts' ),
			array( 'mkam-ai-insights', __( 'AI Insights', 'merchantkits-attendance-manager' ), 'render_ai_insights' ),
			array( 'mkam-settings', __( 'Settings', 'merchantkits-attendance-manager' ), 'render_settings' ),
		);

		foreach ( $pages as $page ) {
			add_submenu_page(
				self::MENU_SLUG,
				$page[1],
				$page[1],
				$cap,
				$page[0],
				array( $this, $page[2] )
			);
		}

		// Rename the auto-created first submenu from the parent slug label.
		global $submenu;
		if ( isset( $submenu[ self::MENU_SLUG ][0] ) ) {
			$submenu[ self::MENU_SLUG ][0][0] = __( 'Dashboard', 'merchantkits-attendance-manager' ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
		}
	}

	/**
	 * Enqueue admin CSS/JS on plugin pages only.
	 *
	 * @param string $hook Current admin page hook suffix.
	 * @return void
	 */
	public function enqueue_assets( $hook ) {
		if ( false === strpos( $hook, 'mkam' ) ) {
			return;
		}

		wp_enqueue_style(
			'mkam-admin',
			MKAM_PLUGIN_URL . 'assets/css/admin.css',
			array(),
			MKAM_VERSION
		);

		wp_enqueue_script(
			'mkam-admin',
			MKAM_PLUGIN_URL . 'assets/js/admin.js',
			array( 'jquery' ),
			MKAM_VERSION,
			true
		);

		if ( false !== strpos( $hook, 'mkam-ai-insights' ) ) {
			wp_enqueue_script(
				'mkam-ai-insights',
				MKAM_PLUGIN_URL . 'assets/js/ai-insights.js',
				array( 'mkam-admin' ),
				MKAM_VERSION,
				true
			);
		}

		wp_localize_script(
			'mkam-admin',
			'mkamAdmin',
			array(
				'ajaxUrl'   => admin_url( 'admin-ajax.php' ),
				'restUrl'   => esc_url_raw( rest_url( 'mkam/v1' ) ),
				'restNonce' => wp_create_nonce( 'wp_rest' ),
				'nonce'     => wp_create_nonce( 'mkam_admin' ),
				'i18n'    => array(
					'confirmDelete' => __( 'Are you sure you want to delete this item?', 'merchantkits-attendance-manager' ),
				),
			)
		);
	}

	/* ---------------------------------------------------------------------
	 * Settings API
	 * ------------------------------------------------------------------- */

	/**
	 * Register all settings, sections, and fields across the six tabs.
	 *
	 * @return void
	 */
	public function register_settings() {
		$settings = $this->get_settings_schema();

		foreach ( $settings as $option => $args ) {
			register_setting(
				'mkam_settings_' . $args['tab'],
				$option,
				array(
					'type'              => $args['type'],
					'sanitize_callback' => $args['sanitize'],
					'default'           => $args['default'],
				)
			);
		}
	}

	/**
	 * Definition of every option: tab, label, field type, and sanitizer.
	 *
	 * @return array
	 */
	public function get_settings_schema() {
		return array(
			// General.
			'mkam_company_name'                   => array(
				'tab'      => 'general',
				'label'    => __( 'Company Name', 'merchantkits-attendance-manager' ),
				'field'    => 'text',
				'type'     => 'string',
				'sanitize' => 'sanitize_text_field',
				'default'  => get_bloginfo( 'name' ),
			),
			'mkam_financial_year_start'           => array(
				'tab'      => 'general',
				'label'    => __( 'Financial Year Start', 'merchantkits-attendance-manager' ),
				'field'    => 'month',
				'type'     => 'string',
				'sanitize' => array( $this, 'sanitize_month' ),
				'default'  => 'January',
			),
			'mkam_date_format'                    => array(
				'tab'      => 'general',
				'label'    => __( 'Date Format', 'merchantkits-attendance-manager' ),
				'field'    => 'select',
				'options'  => array(
					'Y-m-d' => 'Y-m-d',
					'd/m/Y' => 'd/m/Y',
					'm/d/Y' => 'm/d/Y',
				),
				'type'     => 'string',
				'sanitize' => array( $this, 'sanitize_date_format' ),
				'default'  => 'Y-m-d',
			),
			'mkam_week_start'                     => array(
				'tab'      => 'general',
				'label'    => __( 'Week Starts On', 'merchantkits-attendance-manager' ),
				'field'    => 'day',
				'type'     => 'string',
				'sanitize' => array( $this, 'sanitize_day' ),
				'default'  => 'Monday',
			),
			'mkam_currency'                       => array(
				'tab'      => 'general',
				'label'    => __( 'Currency Symbol', 'merchantkits-attendance-manager' ),
				'field'    => 'text',
				'type'     => 'string',
				'sanitize' => 'sanitize_text_field',
				'default'  => '$',
			),
			// Attendance.
			'mkam_enable_geolocation'             => array(
				'tab'      => 'attendance',
				'label'    => __( 'Capture GPS location on clock in/out', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 0,
			),
			'mkam_restrict_ip'                    => array(
				'tab'      => 'attendance',
				'label'    => __( 'Restrict clock-in to specific IPs', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 0,
			),
			'mkam_allowed_ips'                    => array(
				'tab'      => 'attendance',
				'label'    => __( 'Allowed IPs (comma-separated)', 'merchantkits-attendance-manager' ),
				'field'    => 'textarea',
				'type'     => 'string',
				'sanitize' => 'sanitize_textarea_field',
				'default'  => '',
			),
			'mkam_auto_clock_out'                 => array(
				'tab'      => 'attendance',
				'label'    => __( 'Auto clock-out at shift end', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 1,
			),
			'mkam_auto_clock_out_buffer'          => array(
				'tab'      => 'attendance',
				'label'    => __( 'Auto clock-out buffer (minutes)', 'merchantkits-attendance-manager' ),
				'field'    => 'number',
				'type'     => 'integer',
				'sanitize' => 'absint',
				'default'  => 60,
			),
			'mkam_overtime_threshold'             => array(
				'tab'      => 'attendance',
				'label'    => __( 'Overtime threshold (minutes)', 'merchantkits-attendance-manager' ),
				'field'    => 'number',
				'type'     => 'integer',
				'sanitize' => 'absint',
				'default'  => 30,
			),
			'mkam_enable_clock_in_note'           => array(
				'tab'      => 'attendance',
				'label'    => __( 'Show note field on clock in', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 0,
			),
			'mkam_enable_employee_pin'            => array(
				'tab'      => 'attendance',
				'label'    => __( 'Allow PIN-based clock in on frontend', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 0,
			),
			// Notifications.
			'mkam_notify_admin_clock_in'          => array(
				'tab'      => 'notifications',
				'label'    => __( 'Email admin on every clock in', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 0,
			),
			'mkam_notify_admin_leave_request'     => array(
				'tab'      => 'notifications',
				'label'    => __( 'Email admin on new leave request', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 1,
			),
			'mkam_notify_employee_leave_decision' => array(
				'tab'      => 'notifications',
				'label'    => __( 'Email employee on leave decision', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 1,
			),
			'mkam_admin_email'                    => array(
				'tab'      => 'notifications',
				'label'    => __( 'Admin notification email', 'merchantkits-attendance-manager' ),
				'field'    => 'email',
				'type'     => 'string',
				'sanitize' => 'sanitize_email',
				'default'  => get_option( 'admin_email' ),
			),
			'mkam_enable_weekly_digest'           => array(
				'tab'      => 'notifications',
				'label'    => __( 'AI-generated weekly digest email', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 0,
			),
			'mkam_weekly_digest_day'              => array(
				'tab'      => 'notifications',
				'label'    => __( 'Weekly digest day', 'merchantkits-attendance-manager' ),
				'field'    => 'day',
				'type'     => 'string',
				'sanitize' => array( $this, 'sanitize_day' ),
				'default'  => 'Monday',
			),
			// AI.
			'mkam_openai_api_key'                 => array(
				'tab'      => 'ai',
				'label'    => __( 'OpenAI API Key', 'merchantkits-attendance-manager' ),
				'field'    => 'password',
				'type'     => 'string',
				'sanitize' => array( $this, 'sanitize_api_key' ),
				'default'  => '',
			),
			'mkam_ai_model'                       => array(
				'tab'      => 'ai',
				'label'    => __( 'AI Model', 'merchantkits-attendance-manager' ),
				'field'    => 'select',
				'options'  => array(
					'gpt-4o-mini' => 'gpt-4o-mini',
					'gpt-4o'      => 'gpt-4o',
				),
				'type'     => 'string',
				'sanitize' => array( $this, 'sanitize_ai_model' ),
				'default'  => 'gpt-4o-mini',
			),
			// Advanced.
			'mkam_delete_data_on_uninstall'       => array(
				'tab'      => 'advanced',
				'label'    => __( 'Remove all data when plugin deleted', 'merchantkits-attendance-manager' ),
				'field'    => 'checkbox',
				'type'     => 'boolean',
				'sanitize' => array( $this, 'sanitize_checkbox' ),
				'default'  => 0,
			),
			'mkam_employee_role'                  => array(
				'tab'      => 'advanced',
				'label'    => __( 'Employee self-service role', 'merchantkits-attendance-manager' ),
				'field'    => 'role',
				'type'     => 'string',
				'sanitize' => array( $this, 'sanitize_role' ),
				'default'  => 'subscriber',
			),
			'mkam_items_per_page'                 => array(
				'tab'      => 'advanced',
				'label'    => __( 'Items per page in admin tables', 'merchantkits-attendance-manager' ),
				'field'    => 'number',
				'type'     => 'integer',
				'sanitize' => 'absint',
				'default'  => 20,
			),
		);
	}

	/**
	 * Sanitize a checkbox value to 0/1.
	 *
	 * @param mixed $value Raw value.
	 * @return int
	 */
	public function sanitize_checkbox( $value ) {
		return empty( $value ) ? 0 : 1;
	}

	/**
	 * Validate a weekday name against the allowed list.
	 *
	 * @param mixed $value Raw value.
	 * @return string
	 */
	public function sanitize_day( $value ) {
		$allowed = array( 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' );
		$value   = sanitize_text_field( (string) $value );
		return in_array( $value, $allowed, true ) ? $value : 'Monday';
	}

	/**
	 * Validate a month name against the allowed list.
	 *
	 * @param mixed $value Raw value.
	 * @return string
	 */
	public function sanitize_month( $value ) {
		$allowed = array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' );
		$value   = sanitize_text_field( (string) $value );
		return in_array( $value, $allowed, true ) ? $value : 'January';
	}

	/**
	 * Validate the date format against the allowed choices.
	 *
	 * @param mixed $value Raw value.
	 * @return string
	 */
	public function sanitize_date_format( $value ) {
		$allowed = array( 'Y-m-d', 'd/m/Y', 'm/d/Y' );
		$value   = sanitize_text_field( (string) $value );
		return in_array( $value, $allowed, true ) ? $value : 'Y-m-d';
	}

	/**
	 * Validate the AI model against the allowed choices.
	 *
	 * @param mixed $value Raw value.
	 * @return string
	 */
	public function sanitize_ai_model( $value ) {
		$allowed = array( 'gpt-4o-mini', 'gpt-4o' );
		$value   = sanitize_text_field( (string) $value );
		return in_array( $value, $allowed, true ) ? $value : 'gpt-4o-mini';
	}

	/**
	 * Validate the selected role against existing WordPress roles.
	 *
	 * @param mixed $value Raw value.
	 * @return string
	 */
	public function sanitize_role( $value ) {
		$value = sanitize_key( (string) $value );
		$roles = array_keys( wp_roles()->get_names() );
		return in_array( $value, $roles, true ) ? $value : 'subscriber';
	}

	/**
	 * Sanitize the API key. Preserve the stored key when the field is blank.
	 *
	 * @param string $value Submitted value.
	 * @return string
	 */
	public function sanitize_api_key( $value ) {
		$value = sanitize_text_field( $value );

		if ( '' === $value ) {
			return (string) get_option( 'mkam_openai_api_key', '' );
		}

		return $value;
	}

	/**
	 * Settings tab list (slug => label).
	 *
	 * @return array
	 */
	public function get_tabs() {
		if ( empty( $this->tabs ) ) {
			$this->tabs = array(
				'general'        => __( 'General', 'merchantkits-attendance-manager' ),
				'attendance'     => __( 'Attendance', 'merchantkits-attendance-manager' ),
				'leave_policies' => __( 'Leave Policies', 'merchantkits-attendance-manager' ),
				'notifications'  => __( 'Notifications', 'merchantkits-attendance-manager' ),
				'ai'             => __( 'AI Settings', 'merchantkits-attendance-manager' ),
				'advanced'       => __( 'Advanced', 'merchantkits-attendance-manager' ),
			);
		}

		return $this->tabs;
	}

	/* ---------------------------------------------------------------------
	 * Page renderers
	 * ------------------------------------------------------------------- */

	/**
	 * Verify the current user can access plugin admin pages.
	 *
	 * @return void
	 */
	private function guard() {
		if ( ! current_user_can( MKAM_Core::admin_capability() ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'merchantkits-attendance-manager' ) );
		}
	}

	/**
	 * Load an admin template if it exists, else show a placeholder.
	 *
	 * @param string $template Template file name within templates/admin/.
	 * @param array   $context Variables to expose to the template.
	 * @return void
	 */
	private function view( $template, $context = array() ) {
		$file = MKAM_TEMPLATES_DIR . 'admin/' . $template;

		if ( is_readable( $file ) ) {
			// phpcs:ignore WordPress.PHP.DontExtract.extract_extract
			extract( $context );
			include $file;
			return;
		}

		printf(
			'<div class="wrap"><h1>%s</h1><p>%s</p></div>',
			esc_html( get_admin_page_title() ),
			esc_html__( 'This screen will be available soon.', 'merchantkits-attendance-manager' )
		);
	}

	/**
	 * Dashboard page.
	 *
	 * @return void
	 */
	public function render_dashboard() {
		$this->guard();
		$this->view( 'dashboard.php' );
	}

	/**
	 * Employees page.
	 *
	 * @return void
	 */
	public function render_employees() {
		$this->guard();

		$action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : 'list'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$id     = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		if ( in_array( $action, array( 'add', 'edit' ), true ) ) {
			$employee = ( 'edit' === $action && $id ) ? MKAM_Employee::get( $id ) : array();
			$this->view(
				'employee-form.php',
				array(
					'action'   => $action,
					'employee' => $employee,
					'shifts'   => MKAM_Shift::all( 'active' ),
				)
			);
			return;
		}

		if ( ! class_exists( 'MKAM_Admin_Employees_Table' ) ) {
			require_once MKAM_INCLUDES_DIR . 'class-admin-employees-table.php';
		}

		$table = new MKAM_Admin_Employees_Table();
		$table->prepare_items();

		$add_url = wp_nonce_url(
			add_query_arg(
				array(
					'page'   => 'mkam-employees',
					'action' => 'add',
				),
				admin_url( 'admin.php' )
			),
			'mkam_employee_add'
		);

		echo '<div class="wrap">';
		echo '<h1 class="wp-heading-inline">' . esc_html__( 'Employees', 'merchantkits-attendance-manager' ) . '</h1>';
		echo ' <a href="' . esc_url( $add_url ) . '" class="page-title-action">' . esc_html__( 'Add Employee', 'merchantkits-attendance-manager' ) . '</a>';
		echo '<hr class="wp-header-end" />';
		echo '<form method="get">';
		echo '<input type="hidden" name="page" value="mkam-employees" />';
		$table->search_box( __( 'Search Employees', 'merchantkits-attendance-manager' ), 'mkam-employee' );
		$table->display();
		echo '</form>';
		echo '</div>';
	}

	/**
	 * Attendance page.
	 *
	 * @return void
	 */
	public function render_attendance() {
		$this->guard();

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : 'list';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$id = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0;

		if ( 'view' === $action && $id ) {
			$this->view( 'attendance-detail.php', array( 'record' => MKAM_Attendance::get( $id ) ) );
			return;
		}

		if ( ! class_exists( 'MKAM_Admin_Attendance_Table' ) ) {
			require_once MKAM_INCLUDES_DIR . 'class-admin-attendance-table.php';
		}

		$table = new MKAM_Admin_Attendance_Table();
		$table->prepare_items();

		echo '<div class="wrap">';
		echo '<h1 class="wp-heading-inline">' . esc_html__( 'Attendance', 'merchantkits-attendance-manager' ) . '</h1>';
		echo '<hr class="wp-header-end" />';
		echo '<form method="get">';
		echo '<input type="hidden" name="page" value="mkam-attendance" />';
		$table->search_box( __( 'Search', 'merchantkits-attendance-manager' ), 'mkam-attendance' );
		$table->display();
		echo '</form>';
		echo '</div>';
	}

	/**
	 * Leaves page.
	 *
	 * @return void
	 */
	public function render_leaves() {
		$this->guard();

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : 'list';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$id = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0;

		if ( 'view' === $action && $id ) {
			$this->view( 'leave-detail.php', array( 'leave' => MKAM_Leave::get( $id ) ) );
			return;
		}

		if ( ! class_exists( 'MKAM_Admin_Leaves_Table' ) ) {
			require_once MKAM_INCLUDES_DIR . 'class-admin-leaves-table.php';
		}

		$table = new MKAM_Admin_Leaves_Table();
		$table->prepare_items();

		echo '<div class="wrap">';
		echo '<h1 class="wp-heading-inline">' . esc_html__( 'Leave Requests', 'merchantkits-attendance-manager' ) . '</h1>';
		echo '<hr class="wp-header-end" />';
		echo '<form method="get">';
		echo '<input type="hidden" name="page" value="mkam-leaves" />';
		$table->display();
		echo '</form>';
		echo '</div>';
	}

	/**
	 * Process state-changing row actions early (before any output) so that
	 * redirects can send headers. Runs on admin_init.
	 *
	 * @return void
	 */
	public function handle_row_actions() {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		$page   = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
		$action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : '';
		$id     = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0;
		// phpcs:enable WordPress.Security.NonceVerification.Recommended

		if ( ! $id || '' === $action || 0 !== strpos( $page, 'mkam-' ) ) {
			return;
		}

		if ( ! current_user_can( MKAM_Core::admin_capability() ) ) {
			return;
		}

		switch ( $page ) {
			case 'mkam-employees':
				if ( 'delete' === $action && check_admin_referer( 'mkam_employee_delete_' . $id ) ) {
					MKAM_Employee::delete( $id );
					$this->redirect_notice( 'mkam-employees', 'deleted' );
				}
				break;

			case 'mkam-attendance':
				if ( 'delete' === $action && check_admin_referer( 'mkam_attendance_delete_' . $id ) ) {
					MKAM_Attendance::delete( $id );
					$this->redirect_notice( 'mkam-attendance', 'deleted' );
				}
				break;

			case 'mkam-leaves':
				if ( 'approve' === $action && check_admin_referer( 'mkam_leave_approve_' . $id ) ) {
					MKAM_Leave::approve( $id, get_current_user_id() );
					$this->redirect_notice( 'mkam-leaves', 'approved' );
				}
				if ( 'reject' === $action && check_admin_referer( 'mkam_leave_reject_' . $id ) ) {
					MKAM_Leave::reject( $id, get_current_user_id() );
					$this->redirect_notice( 'mkam-leaves', 'rejected' );
				}
				if ( 'delete' === $action && check_admin_referer( 'mkam_leave_delete_' . $id ) ) {
					MKAM_Leave::delete( $id );
					$this->redirect_notice( 'mkam-leaves', 'deleted' );
				}
				break;
		}
	}

	/**
	 * Redirect to a plugin page with a status notice and exit.
	 *
	 * @param string $page   Page slug.
	 * @param string $notice Notice key.
	 * @return void
	 */
	private function redirect_notice( $page, $notice ) {
		wp_safe_redirect(
			add_query_arg(
				array(
					'page'        => $page,
					'mkam_notice' => $notice,
				),
				admin_url( 'admin.php' )
			)
		);
		exit;
	}

	/**
	 * Shifts page.
	 *
	 * @return void
	 */
	public function render_shifts() {
		$this->guard();
		$this->view( 'shifts.php', array( 'shifts' => MKAM_Shift::all() ) );
	}

	/**
	 * AI Insights page.
	 *
	 * @return void
	 */
	public function render_ai_insights() {
		$this->guard();
		$this->view( 'ai-insights.php' );
	}

	/**
	 * Settings page.
	 *
	 * @return void
	 */
	public function render_settings() {
		$this->guard();

		$tabs       = $this->get_tabs();
		$active_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'general'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( ! array_key_exists( $active_tab, $tabs ) ) {
			$active_tab = 'general';
		}

		$this->view(
			'settings.php',
			array(
				'tabs'       => $tabs,
				'active_tab' => $active_tab,
				'schema'     => $this->get_settings_schema(),
			)
		);
	}

	/**
	 * Handle the add/edit employee form submission.
	 *
	 * @return void
	 */
	public function handle_save_employee() {
		$this->guard();

		check_admin_referer( 'mkam_save_employee' );

		$id = isset( $_POST['employee_id_pk'] ) ? absint( $_POST['employee_id_pk'] ) : 0;

		$data = array(
			'first_name'      => isset( $_POST['first_name'] ) ? sanitize_text_field( wp_unslash( $_POST['first_name'] ) ) : '',
			'last_name'       => isset( $_POST['last_name'] ) ? sanitize_text_field( wp_unslash( $_POST['last_name'] ) ) : '',
			'email'           => isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '',
			'phone'           => isset( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : '',
			'employee_id'     => isset( $_POST['employee_id'] ) ? sanitize_text_field( wp_unslash( $_POST['employee_id'] ) ) : '',
			'department'      => isset( $_POST['department'] ) ? sanitize_text_field( wp_unslash( $_POST['department'] ) ) : '',
			'designation'     => isset( $_POST['designation'] ) ? sanitize_text_field( wp_unslash( $_POST['designation'] ) ) : '',
			'shift_id'        => isset( $_POST['shift_id'] ) ? absint( $_POST['shift_id'] ) : 0,
			'employment_type' => isset( $_POST['employment_type'] ) ? sanitize_text_field( wp_unslash( $_POST['employment_type'] ) ) : 'full_time',
			'hourly_rate'     => isset( $_POST['hourly_rate'] ) ? sanitize_text_field( wp_unslash( $_POST['hourly_rate'] ) ) : '',
			'monthly_salary'  => isset( $_POST['monthly_salary'] ) ? sanitize_text_field( wp_unslash( $_POST['monthly_salary'] ) ) : '',
			'join_date'       => isset( $_POST['join_date'] ) ? sanitize_text_field( wp_unslash( $_POST['join_date'] ) ) : '',
			'wp_user_id'      => isset( $_POST['wp_user_id'] ) ? absint( $_POST['wp_user_id'] ) : 0,
			'status'          => isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : 'active',
		);

		$result = $id ? MKAM_Employee::update( $id, $data ) : MKAM_Employee::create( $data );

		$notice = is_wp_error( $result ) ? 'error' : ( $id ? 'updated' : 'created' );
		$this->redirect_notice( 'mkam-employees', $notice );
	}

	/**
	 * Display a transient admin notice based on the mkam_notice query arg.
	 *
	 * @return void
	 */
	public function maybe_show_notice() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( empty( $_GET['mkam_notice'] ) || empty( $_GET['page'] ) || false === strpos( sanitize_key( wp_unslash( $_GET['page'] ) ), 'mkam' ) ) {
			return;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$notice = sanitize_key( wp_unslash( $_GET['mkam_notice'] ) );

		$messages = array(
			'created'  => __( 'Saved successfully.', 'merchantkits-attendance-manager' ),
			'updated'  => __( 'Updated successfully.', 'merchantkits-attendance-manager' ),
			'deleted'  => __( 'Deleted successfully.', 'merchantkits-attendance-manager' ),
			'approved' => __( 'Leave request approved.', 'merchantkits-attendance-manager' ),
			'rejected' => __( 'Leave request rejected.', 'merchantkits-attendance-manager' ),
		);

		if ( 'error' === $notice ) {
			printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', esc_html__( 'There was a problem saving. Please check the fields and try again.', 'merchantkits-attendance-manager' ) );
			return;
		}

		if ( isset( $messages[ $notice ] ) ) {
			printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', esc_html( $messages[ $notice ] ) );
		}
	}
}
