<?php

if (!function_exists('policy_md_upload_path')) {
    /**
     * Full path to the saved markdown file for a policy PDF file name.
     */
    function policy_md_upload_path(string $pdfFileName): string
    {
        $mdFileName = preg_replace('/\.pdf$/i', '.md', $pdfFileName);

        if ($mdFileName === $pdfFileName) {
            $mdFileName .= '.md';
        }

        return WRITEPATH . 'uploads/policy/policy_md/' . $mdFileName;
    }
}

if (!function_exists('policy_pdf_md_path')) {
    /**
     * Resolve markdown path using the same base name as the PDF file.
     * e.g. 1764999905_abc.pdf -> policy_md/1764999905_abc.md
     */
    function policy_pdf_md_path(string $pdfPath): string
    {
        return policy_md_upload_path(basename($pdfPath));
    }
}

if (!function_exists('policy_md_is_valid')) {
    /**
     * Validate that markdown content looks like extracted policy text.
     */
    function policy_md_is_valid(string $content): bool
    {
        $content = trim($content);

        if ($content === '' || strlen($content) < 500) {
            return false;
        }

        $errorMarkers = [
            'pdftotext:',
            'GLIBCXX_',
            'CXXABI_',
            'no version information available',
        ];

        foreach ($errorMarkers as $marker) {
            if (stripos($content, $marker) !== false) {
                return false;
            }
        }

        return true;
    }
}

if (!function_exists('policy_pdf_extract_text')) {
    /**
     * Extract plain text from a PDF using pdftotext (poppler).
     * Uses a clean environment so LAMPP lib paths do not break pdftotext.
     */
    function policy_pdf_extract_text(string $pdfPath): string
    {
        $pdftotext = getenv('PDFTOTEXT_BIN') ?: '/usr/bin/pdftotext';

        if (!is_executable($pdftotext) && $pdftotext === '/usr/bin/pdftotext') {
            $which = trim((string) shell_exec('command -v pdftotext 2>/dev/null'));
            if ($which !== '') {
                $pdftotext = $which;
            }
        }

        $command = sprintf(
            'env -i PATH=/usr/bin:/bin LD_LIBRARY_PATH= %s -layout %s - 2>&1',
            escapeshellcmd($pdftotext),
            escapeshellarg($pdfPath)
        );

        $text = shell_exec($command);

        if (!is_string($text)) {
            return '';
        }

        $text = trim($text);

        if (!policy_md_is_valid($text)) {
            log_message('error', 'PDF text extraction failed or returned invalid content for: ' . $pdfPath);

            return '';
        }

        return $text;
    }
}

if (!function_exists('convert_policy_pdf_to_markdown')) {
    /**
     * Convert a policy PDF to markdown, save to policy_md/, then read back from storage.
     *
     * Always pass $originalPdfFileName (DB/storage name) when $pdfPath is an S3 temp download
     * like /tmp/s3_<uniqid>_original.pdf so the MD key matches the original PDF basename.
     *
     * @return array{status: string, message: string, content?: string, md_path?: string, md_file_name?: string}
     */
    function convert_policy_pdf_to_markdown(string $pdfPath, bool $forceRefresh = false, ?string $originalPdfFileName = null): array
    {
        if (!is_file($pdfPath)) {
            return [
                'status'  => 'failed',
                'message' => "PDF file not found at {$pdfPath}",
            ];
        }

        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mimeType = finfo_file($finfo, $pdfPath);
        finfo_close($finfo);

        if ($mimeType !== 'application/pdf') {
            return [
                'status'  => 'failed',
                'message' => "Unsupported file type ({$mimeType}). Only PDF is supported.",
            ];
        }

        // Prefer the original storage/DB PDF name so S3 temp paths do not pollute the MD key.
        $sourcePdfName = ($originalPdfFileName !== null && $originalPdfFileName !== '')
            ? basename($originalPdfFileName)
            : basename($pdfPath);

        $mdPath     = policy_md_upload_path($sourcePdfName);
        $mdFileName = basename($mdPath);
        $mdDir      = dirname($mdPath);

        if (!is_dir($mdDir) && !mkdir($mdDir, 0777, true) && !is_dir($mdDir)) {
            log_message('error', "Unable to create markdown directory at {$mdDir}; will rely on storage put only");
        }

        if (!$forceRefresh && policy_md_exists($mdFileName)) {
            $cached = policy_read_md($mdFileName);

            if ($cached !== '' && policy_md_is_valid($cached)) {
                log_message('info', "Using cached policy markdown: {$mdFileName}");

                return [
                    'status'       => 'success',
                    'message'      => 'Cached markdown loaded from storage',
                    'content'      => $cached,
                    'md_path'      => $mdPath,
                    'md_file_name' => $mdFileName,
                ];
            }

            log_message('info', "Invalid cached markdown detected, reconverting: {$mdFileName}");
        }

        $extractedText = policy_pdf_extract_text($pdfPath);

        if ($extractedText === '') {
            return [
                'status'  => 'failed',
                'message' => 'PDF text extraction failed. The file may be scanned, image-based, or pdftotext is unavailable on the server.',
            ];
        }

        $markdown = "# Motor Policy Document\n\n" . $extractedText;

        // Local write is best-effort (S3 driver may not have write access under writable/).
        $localWritten = false;
        if (is_dir($mdDir) || (is_dir(dirname($mdDir)) && @mkdir($mdDir, 0777, true))) {
            $localWritten = @file_put_contents($mdPath, $markdown) !== false;
            if (!$localWritten) {
                log_message('error', "Local markdown write failed (continuing with storage put): {$mdPath}");
            }
        }

        policy_put_md($mdFileName, $markdown);

        $savedContent = $localWritten ? (file_get_contents($mdPath) ?: $markdown) : $markdown;

        if (!policy_md_is_valid($savedContent)) {
            if ($localWritten) {
                @unlink($mdPath);
            }

            return [
                'status'  => 'failed',
                'message' => 'Saved markdown file is invalid after conversion',
            ];
        }

        log_message('info', "Policy PDF converted to markdown: {$mdFileName} (local_written=" . ($localWritten ? '1' : '0') . ')');

        return [
            'status'       => 'success',
            'message'      => 'PDF converted to markdown and saved to storage',
            'content'      => $savedContent,
            'md_path'      => $mdPath,
            'md_file_name' => $mdFileName,
        ];
    }
}
