<?php

declare(strict_types=1);

/*
 * This file is part of contao-weinanlieferung-bundle.
 *
 * (c) vonRotenberg
 *
 * @license commercial
 */

namespace vonRotenberg\WeinanlieferungBundle\Model;

use Contao\Model;

class WeinanlieferungStandortModel extends Model
{
    /**
     * Table name
     * @var string
     */
    protected static $strTable = 'tl_vr_wa_standort';

    /**
     * Extracts all possible numbers from the number_ranges field.
     * Expands ranges like "0000-0002" into individual numbers: "0000", "0001", "0002".
     *
     * @param array $excludeNumbers Optional array of numbers to exclude from the result
     * @param int $limit Optional limit to return only a specific number of results
     * @return array Array of extracted numbers
     */
    public function extractNumbersFromRanges(array $excludeNumbers = [], int $limit = 0): array
    {
        $result = [];
        $ranges = $this->number_ranges;
        $excludeLookup = array_flip($excludeNumbers); // For faster lookups

        if (empty($ranges)) {
            return $result;
        }

        // Split by line breaks and other common separators
        $lines = preg_split('/[\r\n,;]+/', $ranges);

        foreach ($lines as $line) {
            $line = trim($line);
            if (empty($line)) {
                continue;
            }

            // Check if it's a range (contains a hyphen)
            if (strpos($line, '-') !== false) {
                list($start, $end) = array_map('trim', explode('-', $line, 2));

                // Ensure both start and end are valid
                if (is_numeric($start) && is_numeric($end)) {
                    // Get the padding length from the start number
                    $padLength = strlen($start);

                    // Convert to integers for the range calculation
                    $startNum = intval($start);
                    $endNum = intval($end);

                    // Generate numbers in the range, but check limit
                    for ($i = $startNum; $i <= $endNum; $i++) {
                        $number = str_pad((string)$i, $padLength, '0', STR_PAD_LEFT);

                        // Skip if this number should be excluded
                        if (isset($excludeLookup[$number])) {
                            continue;
                        }

                        $result[] = $number;

                        // Check if we've reached the limit
                        if ($limit > 0 && count($result) >= $limit) {
                            return $result;
                        }
                    }
                } else {
                    // If not a valid range, treat as a single number
                    if (!isset($excludeLookup[$line])) {
                        $result[] = $line;

                        // Check if we've reached the limit
                        if ($limit > 0 && count($result) >= $limit) {
                            return $result;
                        }
                    }
                }
            } else {
                // It's a single number
                if (!isset($excludeLookup[$line])) {
                    $result[] = $line;

                    // Check if we've reached the limit
                    if ($limit > 0 && count($result) >= $limit) {
                        return $result;
                    }
                }
            }
        }

        return $result;
    }

    /**
     * Returns the count of all possible numbers from the number_ranges field
     * without actually generating all the numbers.
     *
     * @return int Count of all possible numbers
     */
    public function countNumbersInRanges(): int
    {
        $count = 0;
        $ranges = $this->number_ranges;

        if (empty($ranges)) {
            return $count;
        }

        // Split by line breaks and other common separators
        $lines = preg_split('/[\r\n,;]+/', $ranges);

        foreach ($lines as $line) {
            $line = trim($line);
            if (empty($line)) {
                continue;
            }

            // Check if it's a range (contains a hyphen)
            if (strpos($line, '-') !== false) {
                list($start, $end) = array_map('trim', explode('-', $line, 2));

                // Ensure both start and end are valid
                if (is_numeric($start) && is_numeric($end)) {
                    // Convert to integers for the range calculation
                    $startNum = intval($start);
                    $endNum = intval($end);

                    // Add the count of numbers in this range
                    $count += ($endNum - $startNum + 1);
                } else {
                    // If not a valid range, count as a single number
                    $count++;
                }
            } else {
                // It's a single number
                $count++;
            }
        }

        return $count;
    }
}