<?php
/**
 * Shift data model.
 *
 * @package MerchantKits\AttendanceManager
 */

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

/**
 * CRUD wrapper for the mkam_shifts table.
 */
class MKAM_Shift {

	/**
	 * Return the shifts table name.
	 *
	 * @return string
	 */
	public static function table() {
		global $wpdb;
		return $wpdb->prefix . 'mkam_shifts';
	}

	/**
	 * Get a single shift by ID.
	 *
	 * @param int $id Shift ID.
	 * @return array|null Associative row or null when not found.
	 */
	public static function get( $id ) {
		global $wpdb;
		$table = self::table();

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$row = $wpdb->get_row(
			$wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", absint( $id ) ), // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			ARRAY_A
		);

		return $row ? $row : null;
	}

	/**
	 * Get all shifts, optionally filtered by status.
	 *
	 * @param string $status Optional status filter ('active', 'inactive', or '' for all).
	 * @return array List of shift rows.
	 */
	public static function all( $status = '' ) {
		global $wpdb;
		$table = self::table();

		if ( '' !== $status ) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			return $wpdb->get_results(
				$wpdb->prepare( "SELECT * FROM {$table} WHERE status = %s ORDER BY name ASC", sanitize_text_field( $status ) ), // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				ARRAY_A
			);
		}

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
		return $wpdb->get_results( "SELECT * FROM {$table} ORDER BY name ASC", ARRAY_A );
	}

	/**
	 * Sanitize a raw shift data array.
	 *
	 * @param array $data Raw input.
	 * @return array Sanitized data with DB formats applied where relevant.
	 */
	protected static function sanitize( $data ) {
		$clean = array();

		if ( isset( $data['name'] ) ) {
			$clean['name'] = sanitize_text_field( $data['name'] );
		}
		if ( isset( $data['start_time'] ) ) {
			$clean['start_time'] = sanitize_text_field( $data['start_time'] );
		}
		if ( isset( $data['end_time'] ) ) {
			$clean['end_time'] = sanitize_text_field( $data['end_time'] );
		}
		if ( isset( $data['grace_minutes'] ) ) {
			$clean['grace_minutes'] = absint( $data['grace_minutes'] );
		}
		if ( isset( $data['is_overnight'] ) ) {
			$clean['is_overnight'] = empty( $data['is_overnight'] ) ? 0 : 1;
		}
		if ( isset( $data['working_days'] ) ) {
			$days = is_array( $data['working_days'] ) ? implode( ',', array_map( 'absint', $data['working_days'] ) ) : sanitize_text_field( $data['working_days'] );
			$clean['working_days'] = $days;
		}
		if ( isset( $data['break_minutes'] ) ) {
			$clean['break_minutes'] = absint( $data['break_minutes'] );
		}
		if ( isset( $data['status'] ) ) {
			$clean['status'] = sanitize_text_field( $data['status'] );
		}

		return $clean;
	}

	/**
	 * Create a shift.
	 *
	 * @param array $data Raw shift data.
	 * @return int|WP_Error New shift ID or error.
	 */
	public static function create( $data ) {
		global $wpdb;

		$clean = self::sanitize( $data );

		if ( empty( $clean['name'] ) || empty( $clean['start_time'] ) || empty( $clean['end_time'] ) ) {
			return new WP_Error( 'mkam_shift_invalid', __( 'Shift name, start time, and end time are required.', 'merchantkits-attendance-manager' ) );
		}

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$result = $wpdb->insert( self::table(), $clean );

		if ( false === $result ) {
			return new WP_Error( 'mkam_shift_insert_failed', __( 'Could not create the shift.', 'merchantkits-attendance-manager' ) );
		}

		return (int) $wpdb->insert_id;
	}

	/**
	 * Update a shift.
	 *
	 * @param int   $id   Shift ID.
	 * @param array $data Raw shift data.
	 * @return bool|WP_Error True on success or error.
	 */
	public static function update( $id, $data ) {
		global $wpdb;

		$clean = self::sanitize( $data );

		if ( empty( $clean ) ) {
			return new WP_Error( 'mkam_shift_no_data', __( 'No valid shift data supplied.', 'merchantkits-attendance-manager' ) );
		}

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$result = $wpdb->update( self::table(), $clean, array( 'id' => absint( $id ) ) );

		if ( false === $result ) {
			return new WP_Error( 'mkam_shift_update_failed', __( 'Could not update the shift.', 'merchantkits-attendance-manager' ) );
		}

		return true;
	}

	/**
	 * Delete a shift.
	 *
	 * @param int $id Shift ID.
	 * @return bool True on success.
	 */
	public static function delete( $id ) {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		return (bool) $wpdb->delete( self::table(), array( 'id' => absint( $id ) ), array( '%d' ) );
	}
}
