<?php

namespace App\Support;

use App\Services\MathFormulaProcessor;

/**
 * 与判卷页 components/exam/paper-body 选择题题干处理口径一致：
 * 去题号前缀、separateStemAndOptions 分离选项、填空占位虚线、MathFormulaProcessor::processFormulas
 */
class GradingStyleQuestionStem
{
    /**
     * 选项字母映射由下方 separateStemAndOptions / extractOptions 从正文解析；与判卷页一致。
     */
    public static function buildChoiceStemForReport(string $rawQuestionText): string
    {
        $html = is_string($rawQuestionText) ? $rawQuestionText : '';
        $cleanContent = preg_replace('/^\d+[\.、]\s*/', '', trim($html));

        [$stemLine] = self::separateStemAndOptions($cleanContent);

        $renderedStem = self::applyBlankPlaceholdersLikeGrading($stemLine);

        return MathFormulaProcessor::processFormulas($renderedStem);
    }

    /**
     * 与 ExamPdfController::separateStemAndOptions 一致
     *
     * @return array{0: string, 1: array<int, string>}
     */
    public static function separateStemAndOptions(string $content): array
    {
        $contentWithoutSvg = preg_replace('/<svg[^>]*>.*?<\/svg>/is', '[SVG_PLACEHOLDER]', $content);

        $hasOptions = preg_match('/(?:^|\s)[A-D][\.、：．:]/u', $contentWithoutSvg);

        if (! $hasOptions) {
            return [$content, []];
        }

        $options = self::extractOptions($content);

        if (! empty($options)) {
            if (preg_match('/^(.+?)(?=(?:^|\s)[A-D][\.、：．:])/su', $contentWithoutSvg, $match)) {
                $stem = trim($match[1]);
                if (strpos($stem, '[SVG_PLACEHOLDER]') !== false) {
                    foreach (['A.', 'A、', 'A：', 'A．', 'A:'] as $marker) {
                        if (preg_match('/\s'.preg_quote($marker, '/').'/', $content, $m, PREG_OFFSET_CAPTURE)) {
                            $pos = $m[0][1];
                            if ($pos > 0) {
                                $stem = trim(mb_substr($content, 0, $pos));
                                break;
                            }
                        }
                    }
                }
            } else {
                $stem = $content;
                foreach (['A.', 'A、', 'A：', 'A．', 'A:'] as $marker) {
                    if (preg_match('/\s'.preg_quote($marker, '/').'/', $content, $m, PREG_OFFSET_CAPTURE)) {
                        $pos = $m[0][1];
                        if ($pos > 0) {
                            $stem = trim(mb_substr($content, 0, $pos));
                            break;
                        }
                    }
                }
            }

            $stem = preg_replace('/（）\s*$/', '', $stem);
            $stem = trim($stem);

            return [$stem, $options];
        }

        return [$content, []];
    }

    /**
     * 与 ExamPdfController::extractOptions 一致
     *
     * @return array<int, string>
     */
    public static function extractOptions(string $content): array
    {
        $options = [];
        $contentWithoutSvg = preg_replace('/<svg[^>]*>.*?<\/svg>/is', '[SVG_PLACEHOLDER]', $content);
        $pattern = '/(?:^|\s)([A-D])[\.、：．:]\s*(.+?)(?=(?:^|\s)[A-D][\.、：．:]|$)/su';

        if (preg_match_all($pattern, $contentWithoutSvg, $matches, PREG_SET_ORDER)) {
            foreach ($matches as $match) {
                $optionText = trim($match[2]);
                $optionText = preg_replace('/\s+$/', '', $optionText);
                $optionText = preg_replace('/^\$\$\s*/', '', $optionText);
                $optionText = preg_replace('/\s*\$\$$/', '', $optionText);
                if (! empty($optionText)) {
                    $options[] = $optionText;
                }
            }
        }

        if (empty($options)) {
            $lines = preg_split('/[\r\n]+/', $contentWithoutSvg);
            foreach ($lines as $line) {
                $line = trim($line);
                if (preg_match('/^([A-D])[\.、：．:]\s*(.+)$/u', $line, $match)) {
                    $optionText = trim($match[2]);
                    if (! empty($optionText)) {
                        $options[] = $optionText;
                    }
                }
            }
        }

        return $options;
    }

    /**
     * 与 paper-body 选择题中 $renderedStem 逻辑一致
     */
    private static function applyBlankPlaceholdersLikeGrading(string $stemLine): string
    {
        $blankSpan = '<span style="display:inline-block; min-width:80px; border-bottom:1.2px dashed #444; vertical-align:bottom;">&nbsp;</span>';
        $renderedStem = $stemLine;
        $renderedStem = preg_replace('/\\\underline\{[^}]*\}/', $blankSpan, $renderedStem);
        $renderedStem = preg_replace('/\\\qquad+/', $blankSpan, $renderedStem);

        $latexPlaceholders = [];
        $counter = 0;
        $renderedStem = preg_replace_callback('/\$[^$]+\$/u', function ($matches) use (&$latexPlaceholders, &$counter) {
            $placeholder = '<<<LATEX_'.$counter.'>>>';
            $latexPlaceholders[$placeholder] = $matches[0];
            $counter++;

            return $placeholder;
        }, $renderedStem);

        $renderedStem = preg_replace(['/（\s*）/u', '/\(\s*\)/', '/_{2,}/'], $blankSpan, $renderedStem);

        foreach ($latexPlaceholders as $placeholder => $latexContent) {
            $encodedLatex = htmlspecialchars($latexContent, ENT_QUOTES | ENT_HTML5, 'UTF-8');
            $renderedStem = str_replace($placeholder, $encodedLatex, $renderedStem);
        }

        if ($renderedStem === $stemLine) {
            $renderedStem .= ' '.$blankSpan;
        }

        return $renderedStem;
    }
}
