<?php

declare(strict_types=1);

/**
 * Multi-inbound selection per plan (server_plans.inbound_ids JSON + legacy inbound_id).
 */
class PlanInboundIds
{
    public static function ensureSchema(mysqli $conn): void
    {
        $res = $conn->query("SHOW COLUMNS FROM server_plans LIKE 'inbound_ids'");
        if ($res && $res->num_rows === 0) {
            $conn->query("ALTER TABLE server_plans ADD COLUMN inbound_ids TEXT NULL DEFAULT NULL AFTER inbound_id");
            $conn->query(
                "UPDATE server_plans SET inbound_ids = CONCAT('[', inbound_id, ']')
                 WHERE inbound_id > 0 AND (inbound_ids IS NULL OR inbound_ids = '' OR inbound_ids = '[]')"
            );
        }
    }

    /** @return int[] */
    public static function parse(?string $stored, int $legacyInboundId = 0): array
    {
        if ($stored !== null && $stored !== '' && $stored !== '[]') {
            $decoded = json_decode($stored, true);
            if (is_array($decoded)) {
                $ids = array_values(array_unique(array_filter(array_map('intval', $decoded))));
                if (!empty($ids)) {
                    return $ids;
                }
            }
        }
        if ($legacyInboundId > 0) {
            return [$legacyInboundId];
        }
        return [];
    }

    /** @return int[] */
    public static function parseFromRow(array $row): array
    {
        return self::parse($row['inbound_ids'] ?? null, (int) ($row['inbound_id'] ?? 0));
    }

    /** @param int[] $ids */
    public static function encode(array $ids): string
    {
        $ids = array_values(array_unique(array_filter(array_map('intval', $ids))));
        sort($ids);
        return json_encode($ids, JSON_UNESCAPED_UNICODE);
    }

    /** Legacy column: first selected id, or 0 when none (inbound_id=0 => dedicated plan). */
    /** @param int[] $ids */
    public static function legacyInboundId(array $ids): int
    {
        return empty($ids) ? 0 : (int) $ids[0];
    }

    public static function planUsesInbounds(array $row): bool
    {
        return !empty(self::parseFromRow($row));
    }

    /** @param int[] $ids @param int[] $livePanelIds @return int[] */
    public static function intersectWithLive(array $ids, array $livePanelIds): array
    {
        if (empty($ids)) {
            return [];
        }
        $live = array_flip(array_map('intval', $livePanelIds));
        return array_values(array_filter($ids, static function ($id) use ($live) {
            return isset($live[(int) $id]);
        }));
    }

    /** @param int[] $ids */
    public static function updatePlanRow(mysqli $conn, int $planId, array $ids): void
    {
        if ($planId <= 0) {
            return;
        }
        $json = self::encode($ids);
        $legacy = self::legacyInboundId($ids);
        $stmt = $conn->prepare('UPDATE server_plans SET inbound_ids = ?, inbound_id = ? WHERE id = ?');
        $stmt->bind_param('sii', $json, $legacy, $planId);
        $stmt->execute();
        $stmt->close();
    }

    /** SQL fragment for listing inbound-based (multi) plans. */
    public static function sqlHasInboundsCondition(): string
    {
        return "( (inbound_ids IS NOT NULL AND inbound_ids <> '' AND inbound_ids <> '[]') OR inbound_id > 0 )";
    }
}
