<?php

namespace ShopManagerPro\Filters;

use ShopManagerPro\Filters\DTO\Generated\Filter;
use ShopManagerPro\Filters\DTO\Generated\FilterConditionsItem;
use ShopManagerPro\Shared\DatabaseManagerService;
use ShopManagerPro\Shared\Utils\Logger;

class FilterRepository {
	public static function getFilters() {
		global $wpdb;
		$results = $wpdb->get_results('SELECT * FROM '.DatabaseManagerService::$filtersTableName.' ORDER BY created_at DESC', ARRAY_A);
		$filters = [];
		foreach ($results as $row) {
			try {
				$filters[] = self::createFilterFromRow($row);
			} catch (\Throwable $e) {
				Logger::exception('Failed to create filter from row', $e, ['row' => $row]);
			}
		}

return $filters;
	}

	public static function getFilter(int $id) {
		global $wpdb;
		$row = $wpdb->get_row($wpdb->prepare('SELECT * FROM '.DatabaseManagerService::$filtersTableName.' WHERE id = %d', $id), ARRAY_A);
		if (!$row) {
			return null;
		} try {
			return self::createFilterFromRow($row);
		} catch (\Throwable $e) {
			Logger::exception('Failed to create filter from row', $e, ['row' => $row]);

			return null;
		}
	}

	public static function createFilter(Filter $filter) {
		global $wpdb;
		$current_time = current_time('mysql', true);
		$current_user_id = get_current_user_id();
		$conditionsArray = array_map(function ($condition) { return $condition->toJson(); }, $filter->getConditions());
		$result = $wpdb->insert(DatabaseManagerService::$filtersTableName, ['created_by' => $current_user_id ?: null, 'name' => $filter->getName(), 'filter_conditions' => \ShopManagerPro\Shared\Utils\JSON::encode($conditionsArray), 'created_at' => $current_time, 'updated_at' => $current_time], ['%d', '%s', '%s', '%s', '%s']);
		if ($result === false) {
			throw new \Exception('Failed to create filter: '.$wpdb->last_error);
		}

return $wpdb->insert_id;
	}

	public static function updateFilter(Filter $filter) {
		global $wpdb;
		$conditionsArray = array_map(function (FilterConditionsItem $condition) { return $condition->toJson(); }, $filter->getConditions());
		$result = $wpdb->update(DatabaseManagerService::$filtersTableName, ['name' => $filter->getName(), 'filter_conditions' => \ShopManagerPro\Shared\Utils\JSON::encode($conditionsArray), 'updated_at' => current_time('mysql', true)], ['id' => $filter->getId()], ['%s', '%s', '%s'], ['%d']);
		if ($result === false) {
			throw new \Exception('Failed to update filter '.$filter->getId().': '.$wpdb->last_error);
		}
	}

	public static function deleteFilter(int $id) {
		global $wpdb;
		$result = $wpdb->delete(DatabaseManagerService::$filtersTableName, ['id' => $id], ['%d']);
		if ($result === false) {
			throw new \Exception('Failed to delete filter '.$id.': '.$wpdb->last_error);
		}
	}

	public static function renameFilter(int $id, string $name) {
		global $wpdb;
		$result = $wpdb->update(DatabaseManagerService::$filtersTableName, ['name' => $name, 'updated_at' => current_time('mysql', true)], ['id' => $id], ['%s', '%s'], ['%d']);
		if ($result === false) {
			throw new \Exception('Failed to rename filter '.$id.' to "'.$name.'": '.$wpdb->last_error);
		}
	}

	private static function createFilterFromRow(array $row) {
		$conditionsData = \ShopManagerPro\Shared\Utils\JSON::decode($row['filter_conditions']);
		$conditions = array_map(function ($conditionData) { return FilterConditionsItem::buildFromInput($conditionData); }, $conditionsData);

		return new Filter(id: (int) $row['id'], name: $row['name'], conditions: $conditions);
	}
}
