<?php

if (!defined('ABSPATH')) {
    exit;
}

class Ansico_Diagnosekoder_Parser {
    public static function parse_file($file_path) {
        if (!file_exists($file_path) || !is_readable($file_path)) {
            return [
                'rows' => [],
                'meta' => [
                    'error' => __('Filen kunne ikke læses.', 'ansico-diagnosekoder'),
                ],
            ];
        }

        $handle = fopen($file_path, 'r');
        if (!$handle) {
            return [
                'rows' => [],
                'meta' => [
                    'error' => __('Filen kunne ikke åbnes.', 'ansico-diagnosekoder'),
                ],
            ];
        }

        $rows = [];
        $header_found = false;
        $line_number = 0;

        while (($line = fgets($handle)) !== false) {
            $line_number++;
            $line = trim($line);

            if ($line === '') {
                continue;
            }

            $columns = str_getcsv($line, ';', '"', '\\');
            if (!is_array($columns) || count($columns) < 2) {
                continue;
            }

            $col1 = isset($columns[0]) ? trim((string) $columns[0]) : '';
            $col2 = isset($columns[1]) ? trim((string) $columns[1]) : '';

            if (!$header_found) {
                if (strcasecmp($col1, 'Kode') === 0 && strcasecmp($col2, 'Tekst') === 0) {
                    $header_found = true;
                }
                continue;
            }

            if ($col1 === '' || $col2 === '') {
                continue;
            }

            $rows[] = [
                'code' => sanitize_text_field($col1),
                'text' => sanitize_text_field($col2),
            ];
        }

        fclose($handle);

        return [
            'rows' => $rows,
            'meta' => [
                'imported_at' => current_time('mysql'),
                'row_count'    => count($rows),
                'source_name'  => basename($file_path),
                'header_found' => $header_found,
                'line_count'   => $line_number,
            ],
        ];
    }

    public static function search($query, $limit = 50, $favorite_codes = [], $links = []) {
        $query = trim((string) $query);
        if ($query === '') {
            return [];
        }

        $data = get_option(ANSICO_DIAGNOSEKODER_OPTION_DATA, []);
        if (!is_array($data) || empty($data)) {
            return [];
        }

        $limit = $limit > 0 ? min($limit, 100) : 50;
        $query_lower = function_exists('mb_strtolower') ? mb_strtolower($query, 'UTF-8') : strtolower($query);
        $favorite_lookup = [];
        foreach ((array) $favorite_codes as $favorite_code) {
            $favorite_lookup[self::normalize_code($favorite_code)] = true;
        }
        $link_lookup = is_array($links) ? $links : [];

        $results = [];
        foreach ($data as $index => $row) {
            if (!is_array($row) || empty($row['code']) || empty($row['text'])) {
                continue;
            }

            $code = (string) $row['code'];
            $text = (string) $row['text'];
            $normalized_code = self::normalize_code($code);
            $haystack_code = function_exists('mb_strtolower') ? mb_strtolower($code, 'UTF-8') : strtolower($code);
            $haystack_text = function_exists('mb_strtolower') ? mb_strtolower($text, 'UTF-8') : strtolower($text);

            if (strpos($haystack_code, $query_lower) === false && strpos($haystack_text, $query_lower) === false) {
                continue;
            }

            $results[] = [
                'code' => $code,
                'text' => $text,
                'is_favorite' => isset($favorite_lookup[$normalized_code]),
                'linked_url' => isset($link_lookup[$normalized_code]) ? $link_lookup[$normalized_code] : '',
                '_original_index' => $index,
            ];
        }

        if (empty($results)) {
            return [];
        }

        usort($results, static function ($a, $b) {
            $a_favorite = !empty($a['is_favorite']);
            $b_favorite = !empty($b['is_favorite']);

            if ($a_favorite !== $b_favorite) {
                return $a_favorite ? -1 : 1;
            }

            return ((int) ($a['_original_index'] ?? 0)) <=> ((int) ($b['_original_index'] ?? 0));
        });

        foreach ($results as &$result) {
            unset($result['_original_index']);
        }
        unset($result);

        return array_slice($results, 0, $limit);
    }

    public static function get_rows_by_codes($codes = []) {
        $normalized_codes = [];
        foreach ((array) $codes as $code) {
            $normalized = self::normalize_code($code);
            if ($normalized !== '') {
                $normalized_codes[] = $normalized;
            }
        }
        $normalized_codes = array_values(array_unique($normalized_codes));
        if (empty($normalized_codes)) {
            return [];
        }

        $lookup = array_fill_keys($normalized_codes, true);
        $data = get_option(ANSICO_DIAGNOSEKODER_OPTION_DATA, []);
        if (!is_array($data) || empty($data)) {
            return [];
        }

        $rows = [];
        foreach ($data as $row) {
            if (!is_array($row) || empty($row['code']) || empty($row['text'])) {
                continue;
            }

            $code = (string) $row['code'];
            $normalized_code = self::normalize_code($code);
            if (!isset($lookup[$normalized_code])) {
                continue;
            }

            $rows[$normalized_code] = [
                'code' => $code,
                'text' => (string) $row['text'],
            ];
        }

        $ordered = [];
        foreach ($normalized_codes as $normalized_code) {
            if (isset($rows[$normalized_code])) {
                $ordered[] = $rows[$normalized_code];
            }
        }

        return $ordered;
    }

    protected static function normalize_code($code) {
        $code = sanitize_text_field((string) $code);
        $code = preg_replace('/\s+/', '', $code);
        return strtoupper((string) $code);
    }
}
