<?php
/**
 * Group Management Class
 *
 * Handles CRUD operations for training groups
 *
 * @package    Karate_Club_Manager
 * @subpackage Karate_Club_Manager/includes/classes
 * @since      1.0.0
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class MACM_Group
 *
 * Manages training groups (age groups, skill levels, etc.)
 *
 * @since 1.0.0
 */
class MACM_Group {

	/**
	 * Create a new group
	 *
	 * @since 1.0.0
	 * @param array $data Group data.
	 * @return int|WP_Error Group ID on success, WP_Error on failure.
	 */
	public static function create( $data ) {
		global $wpdb;

		// Validate required fields.
		if ( empty( $data['name'] ) ) {
			return new WP_Error( 'missing_name', __( 'Group name is required.', 'martial-arts-club-manager' ) );
		}

		// Validate name length.
		if ( strlen( $data['name'] ) > 100 ) {
			return new WP_Error( 'name_too_long', __( 'Group name must be less than 100 characters.', 'martial-arts-club-manager' ) );
		}

		// Validate description length if provided.
		if ( ! empty( $data['description'] ) && strlen( $data['description'] ) > 500 ) {
			return new WP_Error( 'description_too_long', __( 'Description must be less than 500 characters.', 'martial-arts-club-manager' ) );
		}

		// Prepare data for insertion.
		$insert_data = array(
			'group_name'  => sanitize_text_field( $data['name'] ),
			'description' => ! empty( $data['description'] ) ? sanitize_textarea_field( $data['description'] ) : null,
			'is_active'   => isset( $data['is_active'] ) ? (int) $data['is_active'] : 1,
			'created_at'  => current_time( 'mysql' ),
		);

		$table_name = $wpdb->prefix . 'macm_groups';

		// Insert into database.
		$inserted = $wpdb->insert(
			$table_name,
			$insert_data,
			array( '%s', '%s', '%d', '%s' )
		);

		if ( false === $inserted ) {
			return new WP_Error( 'db_error', __( 'Failed to create group.', 'martial-arts-club-manager' ) );
		}

		$group_id = $wpdb->insert_id;

		// Fire action hook.
		do_action( 'macm_group_created', $group_id, $insert_data );

		return $group_id;
	}

	/**
	 * Get group by ID
	 *
	 * @since 1.0.0
	 * @param int $group_id Group ID.
	 * @return object|false Group object on success, false on failure.
	 */
	public static function get( $group_id ) {
		global $wpdb;

		$table_name = $wpdb->prefix . 'macm_groups';

		$group = $wpdb->get_row(
			$wpdb->prepare(
				'SELECT * FROM %i WHERE id = %d',
				$table_name,
				$group_id
			)
		);

		return $group ? $group : false;
	}

	/**
	 * Get all groups
	 *
	 * @since 1.0.0
	 * @param bool $active_only Whether to return only active groups.
	 * @return array Array of group objects.
	 */
	public static function get_all( $active_only = true ) {
		global $wpdb;

		$table_name = $wpdb->prefix . 'macm_groups';

		if ( $active_only ) {
			$groups = $wpdb->get_results(
				$wpdb->prepare(
					'SELECT * FROM %i WHERE is_active = 1 ORDER BY group_name ASC',
					$table_name
				)
			);
		} else {
			$groups = $wpdb->get_results(
				$wpdb->prepare(
					'SELECT * FROM %i ORDER BY group_name ASC',
					$table_name
				)
			);
		}

		return $groups ? $groups : array();
	}

	/**
	 * Update group
	 *
	 * @since 1.0.0
	 * @param int   $group_id Group ID.
	 * @param array $data Group data to update.
	 * @return bool|WP_Error True on success, WP_Error on failure.
	 */
	public static function update( $group_id, $data ) {
		global $wpdb;

		// Check if group exists.
		$group = self::get( $group_id );
		if ( ! $group ) {
			return new WP_Error( 'not_found', __( 'Group not found.', 'martial-arts-club-manager' ) );
		}

		// Validate name if provided.
		if ( isset( $data['name'] ) ) {
			if ( empty( $data['name'] ) ) {
				return new WP_Error( 'missing_name', __( 'Group name is required.', 'martial-arts-club-manager' ) );
			}
			if ( strlen( $data['name'] ) > 100 ) {
				return new WP_Error( 'name_too_long', __( 'Group name must be less than 100 characters.', 'martial-arts-club-manager' ) );
			}
		}

		// Validate description if provided.
		if ( isset( $data['description'] ) && strlen( $data['description'] ) > 500 ) {
			return new WP_Error( 'description_too_long', __( 'Description must be less than 500 characters.', 'martial-arts-club-manager' ) );
		}

		// Prepare data for update.
		$update_data = array();
		$format      = array();

		if ( isset( $data['name'] ) ) {
			$update_data['group_name'] = sanitize_text_field( $data['name'] );
			$format[]                  = '%s';
		}

		if ( isset( $data['description'] ) ) {
			$update_data['description'] = sanitize_textarea_field( $data['description'] );
			$format[]                   = '%s';
		}

		if ( isset( $data['is_active'] ) ) {
			$update_data['is_active'] = (int) $data['is_active'];
			$format[]                 = '%d';
		}

		if ( empty( $update_data ) ) {
			return new WP_Error( 'no_data', __( 'No data to update.', 'martial-arts-club-manager' ) );
		}

		$table_name = $wpdb->prefix . 'macm_groups';

		// Update database.
		$updated = $wpdb->update(
			$table_name,
			$update_data,
			array( 'id' => $group_id ),
			$format,
			array( '%d' )
		);

		if ( false === $updated ) {
			return new WP_Error( 'db_error', __( 'Failed to update group.', 'martial-arts-club-manager' ) );
		}

		// Fire action hook.
		do_action( 'macm_group_updated', $group_id, $update_data );

		return true;
	}

	/**
	 * Delete group
	 *
	 * Checks if group is in use by any members before deleting
	 *
	 * @since 1.0.0
	 * @param int $group_id Group ID.
	 * @return bool|WP_Error True on success, WP_Error on failure.
	 */
	public static function delete( $group_id ) {
		global $wpdb;

		// Check if group exists.
		$group = self::get( $group_id );
		if ( ! $group ) {
			return new WP_Error( 'not_found', __( 'Group not found.', 'martial-arts-club-manager' ) );
		}

		// Check if group is used by any active members.
		$members_table       = $wpdb->prefix . 'macm_members';
		$member_groups_table = $wpdb->prefix . 'macm_member_groups';

		// Count from junction table, joined with members table to check active status.
		$member_count = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(*)
                FROM %i mg
                INNER JOIN %i m ON mg.member_id = m.id
                WHERE mg.group_id = %d AND m.status = 'active'",
				$member_groups_table,
				$members_table,
				$group_id
			)
		);

		if ( $member_count > 0 ) {
			return new WP_Error(
				'in_use',
				sprintf(
					/* translators: %d: number of members assigned to this group */
					__( 'Cannot delete group. It is assigned to %d active member(s).', 'martial-arts-club-manager' ),
					$member_count
				)
			);
		}

		// Remove group associations from junction table.
		$wpdb->delete(
			$member_groups_table,
			array( 'group_id' => $group_id ),
			array( '%d' )
		);

		$table_name = $wpdb->prefix . 'macm_groups';

		// Delete from database.
		$deleted = $wpdb->delete(
			$table_name,
			array( 'id' => $group_id ),
			array( '%d' )
		);

		if ( false === $deleted ) {
			return new WP_Error( 'db_error', __( 'Failed to delete group.', 'martial-arts-club-manager' ) );
		}

		// Fire action hook.
		do_action( 'macm_group_deleted', $group_id );

		return true;
	}

	/**
	 * Get members in a group
	 *
	 * @since 1.0.0
	 * @param int $group_id Group ID.
	 * @return array Array of member objects.
	 */
	public static function get_members( $group_id ) {
		global $wpdb;

		$members_table       = $wpdb->prefix . 'macm_members';
		$member_groups_table = $wpdb->prefix . 'macm_member_groups';

		// Get members from junction table.
		$members = $wpdb->get_results(
			$wpdb->prepare(
				'SELECT m.*
                FROM %i m
                INNER JOIN %i mg ON m.id = mg.member_id
                WHERE mg.group_id = %d
                ORDER BY m.full_name ASC',
				$members_table,
				$member_groups_table,
				$group_id
			)
		);

		return $members ? $members : array();
	}

	/**
	 * Get member count for a group
	 *
	 * @since 1.0.0
	 * @param int $group_id Group ID.
	 * @return int Active member count.
	 */
	public static function get_member_count( $group_id ) {
		global $wpdb;

		$members_table       = $wpdb->prefix . 'macm_members';
		$member_groups_table = $wpdb->prefix . 'macm_member_groups';

		// Count from junction table, joined with members table to check active status.
		$count = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(*)
                FROM %i mg
                INNER JOIN %i m ON mg.member_id = m.id
                WHERE mg.group_id = %d AND m.status = 'active'",
				$member_groups_table,
				$members_table,
				$group_id
			)
		);

		return (int) $count;
	}

	/**
	 * Check if group name already exists
	 *
	 * @since 1.0.0
	 * @param string $name Group name.
	 * @param int    $exclude_id Group ID to exclude from check (for updates).
	 * @return bool True if exists, false if not.
	 */
	public static function name_exists( $name, $exclude_id = 0 ) {
		global $wpdb;

		$table_name = $wpdb->prefix . 'macm_groups';

		$count = $wpdb->get_var(
			$wpdb->prepare(
				'SELECT COUNT(*) FROM %i WHERE group_name = %s AND id != %d',
				$table_name,
				sanitize_text_field( $name ),
				$exclude_id
			)
		);

		return $count > 0;
	}
}
