<?php

namespace MenulisAi\Pdfgen\Document;

use PhpOffice\PhpWord\TemplateProcessor;
use Exception;

class Ebook implements Document
{
    protected $object;

    public function __construct(string $jsonPath)
    {
        $this->openFile($jsonPath);
    }

    public function templateSource(): string
    {
        return appPath("Template/Ebook.docx");
    }

    public function compile(): string
    {
        $proc = new TemplateProcessor($this->templateSource());

        $proc->setValues([
            'material' => strtoupper($this->object->user_input->category),
            'chapter_name' => strtoupper($this->object->user_input->material),
            'chapter' => '01',
        ]);

        // Backgrounds
        $backgrounds = [];

        foreach ($this->object->outlines->introduction->backgrounds as $back) {
            $backgrounds[]['content_background'] = $back;
        }

        $proc->cloneBlock('block_content_background', 0, true, false, $backgrounds);

        // Urgencies
        $urgencies = [];

        foreach ($this->object->outlines->introduction->urgency_studying_materials as $urgents) {
            $urgencies[]['content_urgency'] = $urgents;
        }

        $proc->cloneBlock('block_content_urgency', 0, true, false, $urgencies);

        // Materials
        $proc->cloneBlock('block_content_material', count($this->object->outlines->learning_materials), true, true);

        foreach ($this->object->outlines->learning_materials as $index => $material) {
            $ci = $index + 1;

            // Umum
            $proc->setValues([
                'material_number#' . $ci => $this->intToAlphabet($ci + 1),
                'material_title#' . $ci => $material->title,
                'reflection_number#' . $ci => count($material->materials) + 4,
                'conclusion_number#' . $ci => count($material->materials) + 3,
            ]);

            // Base of competition

            $baseComps = [];

            foreach ($material->objectives as $comp) {
                $baseComps[]['base_comp#' . $ci] = $comp;
            }

            $proc->cloneBlock('block_base_comp#' . $ci, 0, true, false, $baseComps);

            // Pre Questions
            $preQuests = [];

            foreach ($material->starter_questions as $quest) {
                $preQuests[]['pre_question#' . $ci] = $quest;
            }

            $proc->cloneBlock('block_pre_question#' . $ci, 0, true, false, $preQuests);

            // Material
            $proc->cloneBlock('block_sub#' . $ci, count($material->materials), true, true);

            foreach ($material->materials as $key => $sub) {
                $k = $key + 1;
                $proc->setValues([
                    'material_sub_number#' . $ci . '#' . $k => $k + 2,
                    'material_sub_name#' . $ci . '#' . $k => $sub->title,
                    'sub_content#' . $ci . '#' . $k => $sub->full_material,
                ]);
            }

            // Conclusion

            $conclusions = [];
            foreach ($material->summary_material as $con) {
                $conclusions[]['conclusion#' . $ci] = $con;
            }

            $proc->cloneBlock('conclusion_block#' . $ci, 0, true, false, $conclusions);

            // Reflection

            $reflects = [];
            foreach ($material->learning_reflection as $key => $value) {
                $reflects[]['reflection#' . $ci] = $value;
            }

            $proc->cloneBlock('block_reflection#' . $ci, 0, true, false, $reflects);
        }

        return $proc->save();
    }

    protected function openFile(string $path)
    {
        $file = file_get_contents($path);
        if ($file === false) {
            throw new Exception("Unable to read or open the file", 1);
        }

        $data = json_decode($file);
        if (json_last_error() !== JSON_ERROR_NONE) {
            // Handle error if the JSON could not be parsed
            throw new Exception("Error read the json file: " . json_last_error_msg(), 1);
        }

        $this->object = $data;
    }

    protected function intToAlphabet(int $number): string
    {
        return chr(65 + ($number - 1));
    }
}
