<?php
/**
 * Departments manager
 *
 * @package crewhrm
 */

namespace CrewHRM\Models;

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


use CrewHRM\Helpers\_Array;
use CrewHRM\Helpers\_String;

/**
 * The handler class
 */
class Department {
	/**
	 * Save bulk departments. Ideally from department setting page in backend dashboard.
	 *
	 * @param array $departments Departments to save.
	 * @return void
	 */
	public static function saveDepartments( array $departments ) {

		// Apply order the way the array is
		$departments = _Array::addOrderColumn( $departments, 'sequence' );

		// Delete those departments thats ID is not in the current one
		$department_ids = array_column( $departments, 'department_id' );
		$department_ids = array_filter(
			$department_ids,
			function( $id ) {
				return is_numeric( $id );
			}
		);
		self::deleteOutStandings( $department_ids );

		global $wpdb;
		foreach ( $departments as $department ) {

			// Prepare data to update or create
			$payload = array(
				'department_name' => $department['department_name'],
				'sequence'        => $department['sequence'],
				'parent_id'       => $department['parent_id'] ?? null,
			);

			// ID is non numeric when generated by React for new department
			if ( is_numeric( $department['department_id'] ) ) {
				// Update the name as ID exists
				$wpdb->update(
					$wpdb->crewhrm_departments,
					$payload,
					array( 'department_id' => $department['department_id'] )
				);
			} else {
				// The ID was assigned by react when added new for 'key' attribute purpose. Insert it as a new.
				$wpdb->insert(
					$wpdb->crewhrm_departments,
					$payload
				);
			}
		}
	}

	/**
	 * Delete departments that are not in the current array
	 *
	 * @param array $current_ids Current array of department IDs
	 * @return void
	 */
	public static function deleteOutStandings( array $current_ids ) {

		if ( empty( $current_ids ) ) {
			return;
		}

		// Prepare IDs to delete stages by
		$current_ids = array_values( _Array::getArray( $current_ids, false, 0 ) );
		$ids_places  = _String::getPlaceHolders( $current_ids );

		global $wpdb;
		$wpdb->query(
			$wpdb->prepare(// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
				"DELETE FROM 
					%i 
				WHERE 
					department_id NOT IN ({$ids_places})", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				$wpdb->crewhrm_departments,
				...$current_ids
			)
		);
	}

	/**
	 * Get departments
	 *
	 * @return array
	 */
	public static function getDepartments() {
		global $wpdb;
		$departments = $wpdb->get_results(
			"SELECT * FROM {$wpdb->crewhrm_departments} ORDER BY sequence ASC",
			ARRAY_A
		);

		return _Array::getArray( $departments );
	}

	/**
	 * Get single department name by ID
	 *
	 * @param int $department_id The department ID to get name of
	 *
	 * @return string|null
	 */
	public static function getDepartmentNameById( $department_id ) {
		return Field::departments()->getField( array( 'department_id' => $department_id ), 'department_name' );
	}

	/**
	 * Add a single department
	 *
	 * @param string $department_name New name to add as department
	 * @return int
	 */
	public static function addDepartment( string $department_name ) {
		global $wpdb;

		// Get sequence number
		$max_value = $wpdb->get_var(
			"SELECT MAX(sequence) FROM {$wpdb->crewhrm_departments}"
		);

		$new_sequence = $max_value + 1;

		// Insert finally
		$wpdb->insert(
			$wpdb->crewhrm_departments,
			array(
				'department_name' => $department_name,
				'sequence'        => $new_sequence,
			)
		);

		return $wpdb->insert_id;
	}
}
