<?php
$_db_migration_to = '10.07'; // 3.1.4
if (!isset($migrations) || !is_object($migrations))
	die("This file cannot be executed directly");
$migrations->CheckValid($_db_migration_to);
//===========================================================================================



$migrations->Run('20250416_add_private_history_support.php', <<<'DB_UPDATE_FILE'
<?php

$logger = $migrations->getLogger();

try {
	/** @var \Claromentis\Setup\SetupFacade $migrations */
	$db = $migrations->GetDb();

	/** Claromentis\Projects\Permissions::PROJECT_AGGREGATION */
	$PROJECT_AGGREGATION = 121;

	/** Claromentis\Projects\Permissions::TASK_AGGREGATION */
	$PROJECT_AGGREGATION = 122;

	$db->AddColumn('projects_history', 'is_private', 'BOOL NULL DEFAULT 0');

	$assignee_table = [
		'history_id' => 'INT NOT_NULL DEFAULT 0',
		'user_id' => 'INT NOT_NULL DEFAULT 0'
	];
	$db->CreateTable('projects_history_assignees', $assignee_table, true);

	// Add private flags to history entries for existing project.
	// Previous task history can only be seen by people with rights to see the private task so doesn't need this fix

	// Direct task history
	$db->DoTransaction(function() use($db) {
		$res = $db->query("SELECT id, changes FROM projects_history WHERE area='Task'");
		while ($arr = $res->fetchArray())
		{
			$changes = json_decode($arr['changes'], true);
			if (is_array($changes) && array_key_exists('type', $changes) && array_key_exists('changes', $changes) && is_array($changes['changes']))
			{
				if (array_key_exists('is_private', $changes))
				{
					$db->unsafe_query = true;
					$db->query('UPDATE projects_history SET is_private = int:is_private WHERE id eq:int:id', $changes['is_private'] === true ? 1: 0, (int)$arr['id']);
				}

				$assignees = [];
				if ($changes['type'] === 'task_added')
				{
					foreach ($changes['changes'] as $change)
					{
						if ($change['type'] === 'assignees')
							$assignees = array_merge($assignees, $change['value']);
					}
				}
				if ($changes['type'] === 'task_update')
				{
					foreach ($changes['changes'] as $change)
					{
						if ($change['type'] === 'assignees')
							$assignees = array_merge($assignees, $change['new']);
					}
				}

				foreach($assignees as $assignee_user_id)
				{
					if ($assignee_user_id === 0)
						continue;

					$db->unsafe_query = true;
					$db->query('INSERT INTO projects_history_assignees (history_id, user_id) VALUES (int:history_id, int:user_id)', (int)$arr['id'], $assignee_user_id);
				}

			}
		}
	});

	// Project task history
	$db->DoTransaction(function() use($db) {
		$res = $db->query("SELECT id, changes FROM projects_history WHERE area='Project'");
		while ($arr = $res->fetchArray())
		{
			$changes = json_decode($arr['changes'], true);
			if (is_array($changes) && array_key_exists('type', $changes) && $changes['type'] === 'task_deleted')
			{
				if (array_key_exists('is_private', $changes))
				{
					$db->unsafe_query = true;
					$db->query('UPDATE projects_history SET is_private = int:is_private WHERE id eq:int:id', $changes['is_private'] === true ? 1: 0, (int)$arr['id']);
				}

				$assignees = [];
				if (array_key_exists('assignee', $changes))
				{
					$assignees[] = (int)$changes['assignee'];
				}
				if (array_key_exists('assignees', $changes))
				{
					$assignees = array_merge($assignees, array_map(function($user_id){
						return (int)$user_id;
					}, $changes['assignees']));
				}

				foreach($assignees as $assignee_user_id)
				{
					if ($assignee_user_id === 0)
						continue;

					$db->unsafe_query = true;
					$db->query('INSERT INTO projects_history_assignees (history_id, user_id) VALUES (int:history_id, int:user_id)', (int)$arr['id'], $assignee_user_id);
				}
			}
		}
	});
} catch (\Throwable $throwable) {
	$logger->warning($throwable->getMessage());
	$logger->debug($throwable);
}

$logger->notice("If you see warnings such as \"Duplicate column name 'is_private'\", this is expected and not a problem");

DB_UPDATE_FILE
);


//===========================================================================================
$migrations->SetVersion('10.07');
