<?php

namespace MintyPHP\Module\Bookmarks\Repository;

use MintyPHP\DB;

trait SortOrderTrait
{
    abstract protected function sortOrderTableName(): string;

    /** @param list<array{id: int, sort_order: int}> $idOrderPairs */
    public function updateSortOrders(int $userId, array $idOrderPairs): bool
    {
        if ($userId <= 0 || $idOrderPairs === []) {
            return false;
        }

        $idList = [];
        foreach ($idOrderPairs as $pair) {
            $id = (int) $pair['id'];
            if ($id <= 0) {
                return false;
            }
            $idList[] = $id;
        }
        $idList = array_values(array_unique($idList));

        $table = $this->sortOrderTableName();

        $existingCount = DB::selectValue(
            'select count(*) from ' . $table . ' where user_id = ? and id in (???)',
            (string) $userId,
            array_map('strval', $idList)
        );

        if ((int) $existingCount !== count($idList)) {
            return false;
        }

        $db = DB::handle();
        try {
            $db->begin_transaction();

            foreach ($idOrderPairs as $pair) {
                $id = (int) $pair['id'];
                $sortOrder = (int) $pair['sort_order'];
                if ($id <= 0 || $sortOrder <= 0) {
                    $db->rollback();
                    return false;
                }

                $updated = DB::update(
                    'update ' . $table . ' set sort_order = ? where id = ? and user_id = ?',
                    (string) $sortOrder,
                    (string) $id,
                    (string) $userId
                );
                if ($updated === false) {
                    $db->rollback();
                    return false;
                }
            }

            $db->commit();
            return true;
        } catch (\Throwable) {
            try {
                $db->rollback();
            } catch (\Throwable) {
                // no-op
            }
            return false;
        }
    }
}
