<?php

namespace App\Services;

use Exception;
use Illuminate\Support\Facades\Storage;
use mikehaertl\pdftk\Pdf;

class PdfFormService {
    protected string $templatePath;

    public function __construct($templatePath = null) {
        // Ensure standard directory separator is used for the base path
        $defaultPath = Storage::disk('local')->path('templates');
        $this->templatePath = $templatePath ?: $this->normalizePath($defaultPath) . DIRECTORY_SEPARATOR;
    }

    /**
     * Populate a PDF form with data.
     *
     * @param string $templateName The filename of the PDF template.
     * @param array $data Key-value pairs (Field Name => Value).
     * @param string $outputFile Relative path where the output should be stored.
     * @return string Full path to the generated PDF.
     * @throws Exception
     */
    public function fill(string $templateName, array $data, string $outputFile): string {
        $sourceFile = $this->templatePath . $templateName;

        // 1. Verify Source Exists
        if (!file_exists($sourceFile)) {
            throw new Exception("PDF template not found at: {$sourceFile}");
        }

        // 2. Prepare Output Directory
        $fullOutputPath = Storage::disk('public')->path($outputFile);
        $outputDir = dirname($fullOutputPath);

        if (!file_exists($fullOutputPath)) {
            Storage::makeDirectory(dirname($fullOutputPath));
        }

        // 3. Normalize Paths for CLI
        $cleanSource = $this->normalizePath($sourceFile);
        $cleanOutput = $this->normalizePath($fullOutputPath);

        $pdf = new Pdf($cleanSource);

        // 4. Execute pdftk
        $result = $pdf
            ->fillForm($data)
            ->needAppearances()
            ->flatten()
            ->saveAs($cleanOutput);

        // 5. Error Handling
        if ($result === false) {
            $error = $pdf->getError();
            $msg = $error ? $error : "Unknown error (Exit Code 2). This usually happens when trying to fill a dynamic XFA form. Please convert your template to a standard AcroForm (Print to PDF).";
            throw new Exception("PDF could not be generated: " . $msg);
        }

        return $cleanOutput;
    }

    /**
     * DEBUG TOOL: Get a list of all fields in the PDF.
     *
     * @param string $templateName
     * @return string|bool Output from dump_data_fields or false on failure
     */
    public function listFormFields(string $templateName) {
        $sourceFile = $this->templatePath . $templateName;
        $cleanSource = $this->normalizePath($sourceFile);

        $pdf = new Pdf($cleanSource);

        // This executes `pdftk input.pdf dump_data_fields`
        return $pdf->getDataFields();
    }

    /**
     * Helper to ensure paths use the OS specific separator
     */
    private function normalizePath(string $path): string {
        return str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path);
    }
}