<?php

namespace Redirection\ImportExport;

/**
 * Repository wrapper for group lookups and creation.
 *
 * @phpstan-import-type GroupJson from \Red_Group
 * @phpstan-import-type GroupExport from \Red_Group
 */
class GroupRepository {
	/**
	 * @param int $group_id
	 * @return \Red_Group|false
	 */
	public function get( $group_id ) {
		return \Red_Group::get( intval( $group_id, 10 ) );
	}

	/**
	 * @param string $name
	 * @param int $module_id
	 * @param bool $enabled
	 * @return \Red_Group|false
	 */
	public function create( $name, $module_id, $enabled = true ) {
		return \Red_Group::create( $name, $module_id, $enabled );
	}

	/**
	 * @return array<GroupJson>|false
	 */
	public function get_all() {
		return \Red_Group::get_all();
	}

	/**
	 * @param string $name
	 * @return \Red_Group|false
	 */
	public function get_by_name( $name ) {
		$groups = $this->get_all();
		$safe_name = trim( sanitize_text_field( $name ) );

		if ( $groups === false || $safe_name === '' ) {
			return false;
		}

		foreach ( $groups as $group ) {
			if ( ! isset( $group['name'], $group['id'] ) ) {
				continue;
			}

			if ( trim( sanitize_text_field( strval( $group['name'] ) ) ) !== $safe_name ) {
				continue;
			}

			return $this->get( intval( $group['id'], 10 ) );
		}

		return false;
	}

	/**
	 * @param int $module_id
	 * @return array<GroupJson>|false
	 */
	public function get_all_for_module( $module_id ) {
		return \Red_Group::get_all_for_module( intval( $module_id, 10 ) );
	}

	/**
	 * @param int $group_id
	 * @return GroupExport|false
	 */
	public function get_export( $group_id ) {
		$group = $this->get( $group_id );

		if ( $group === false ) {
			return false;
		}

		return $group->to_export();
	}

	/**
	 * @param \Red_Group $group
	 * @param string $name
	 * @param int $module_id
	 * @param bool $enabled
	 * @return \Red_Group
	 */
	public function update( \Red_Group $group, $name, $module_id, $enabled ) {
		$group->update(
			[
				'name' => $name,
				'moduleId' => intval( $module_id, 10 ),
			]
		);

		if ( $enabled ) {
			$group->enable();
		} else {
			$group->disable();
		}

		return $group;
	}

	/**
	 * @return array<GroupExport>
	 */
	public function get_all_for_export() {
		global $wpdb;

		$rows = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}redirection_groups" );

		return array_map(
			static function ( $row ) {
				return ( new \Red_Group( $row ) )->to_export();
			},
			is_array( $rows ) ? $rows : []
		);
	}

	/**
	 * @param int $module_id
	 * @return array<GroupExport>
	 */
	public function get_all_for_module_export( $module_id ) {
		global $wpdb;

		$rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}redirection_groups WHERE module_id=%d", intval( $module_id, 10 ) ) );

		return array_map(
			static function ( $row ) {
				return ( new \Red_Group( $row ) )->to_export();
			},
			is_array( $rows ) ? $rows : []
		);
	}

	/**
	 * @param array<string, mixed> $params
	 * @return array<GroupExport>
	 */
	public function get_filtered_for_export( array $params = [] ) {
		global $wpdb;

		$where = '';

		if ( isset( $params['items'] ) && is_array( $params['items'] ) && count( $params['items'] ) > 0 ) {
			$items = array_values(
				array_filter(
					array_map( 'intval', $params['items'] ),
					static function ( $item ) {
						return $item > 0;
					}
				)
			);

			if ( count( $items ) === 0 ) {
				return [];
			}

			$safe_placeholders = implode( ',', array_fill( 0, count( $items ), '%d' ) );
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $safe_placeholders is built only from the number of sanitized integer items.
			$query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}redirection_groups WHERE id IN ($safe_placeholders)", ...$items );
			$rows = $wpdb->get_results( $query );
		} else {
			if ( isset( $params['filterBy'] ) && is_array( $params['filterBy'] ) ) {
				$filters = new \Red_Group_Filters( $params['filterBy'] );
				$where = $filters->get_as_sql();
			}

			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $where is generated by Red_Group_Filters::get_as_sql() from allowed filter clauses.
			$rows = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}redirection_groups{$where}" );
		}

		return array_map(
			static function ( $row ) {
				return ( new \Red_Group( $row ) )->to_export();
			},
			is_array( $rows ) ? $rows : []
		);
	}
}
