<?php

declare(strict_types=1);

namespace svoboda\pechatalka\controllers;

// Files of the project
use svoboda\pechatalka\controllers\core,
	svoboda\pechatalka\models\paper,
	svoboda\pechatalka\models\product,
	/* svoboda\pechatalka\models\enumerations\paper\type as paper_type, */
	svoboda\pechatalka\models\enumerations\paper\format as paper_format,
	svoboda\pechatalka\models\enumerations\product\type as product_type;

// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
	mirzaev\minimal\http\enumerations\status;

/**
 * Generator
 *
 * @package svoboda\pechatalka\controllers
 *
 * @param array $errors Registry of errors
 *
 * @method null index() Main page
 *
 * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
 * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
 */
final class generator extends core
{
	/**
	 * Errors
	 *
	 * @var array $errors Registry of errors
	 */
	protected array $errors = [
		'system' => []
	];

	/**
	 * Pin
	 *
	 * @return null
	 */
	public function pin(): null
	{
		if (str_contains($this->request->headers['accept'] ?? '', content::any->value)) {
			// Request for any response

			// Render page
			$page = $this->view->render('/generator/pin/page.html');

			// Sending response
			$this->response
				->start()
				->clean()
				->sse()
				->write($page)
				->validate($this->request)
				?->body()
				->end();

			// Deinitializing rendered page
			unset($page);

			// Exit (success)
			return null;
		}

		// Exit (fail)
		return null;
	}

	/**
	 * Print
	 *
	 * Assemble and generate the blank from products and prepare to printing
	 *
	 * @return null
	 */
	public function print(
		string $type = '',
		string $products = '',
		?string $canvas = null
	): null {
		// Type
		!empty($type) and $type = product_type::{$type} ?? null;

		// Amount
		/* preg_match('/[\d]+/', (string) $amount, $matches);
		$amount = (int) $matches[0] ?? 1;
		unset($matches); */

		// Initializing products data
		$products = json_decode($products, true, 16);

		// Initializing the canvas data
		$canvas = json_decode($canvas, true, 16);

		if ($type instanceof product_type && count($products) > 0) {
			// Initialized all required arguments

			// Declaring the images buffer
			$images = [];

			foreach ($this->request->files as $name => $file) {
				// Iterating over received files

				// Deserializing the file type
				!empty($file['type']) && is_string($file['type']) and $file['type'] = content::from($file['type']) ?? null;

				if (match ($file['type']) {
					content::jpeg,
					content::png,
					content::webp => true,
					default => false
				}) {
					// Passed the file type filter

					// Writing into the images buffer
					$images[$name] = $file;
				}
			}

			foreach ($products as $product => &$layers) {
				// Iterating over products

				// Creating the product
				$instance = new product()->create(
					account: 0,
					type: $type,
					layers: $layers,
					canvas: $canvas
				);

				// Initializing the product storage path
				$storage = STORAGE
					. DIRECTORY_SEPARATOR
					. 'products'
					. DIRECTORY_SEPARATOR
					. $instance->identifier;

				if (!file_exists(filename: $storage)) {
					// The product storage directory is not created

					if (mkdir(directory: $storage, permissions: 0755, recursive: true)) {
						// Created the product storage directory
					} else {
						// Nor created the product storage directory

						// Exit (fail)
						return null;
					}
				}

				foreach (array_filter($images, fn(string $key) => preg_match('/^' . $product . '_\d{1,2}$/', $key), ARRAY_FILTER_USE_KEY) as $name => $image) {
					// Iterating over the product images

					// Initializing the layer
					preg_match('/\d{1,2}$/', $name, $matches);
					$layer = $matches[0];

					if (!empty($layer) || $layer == 0) {
						// Initialized the layer

						// Initializing the product layer image file path
						$path = $storage . DIRECTORY_SEPARATOR . $layer . '.' . $image['type']->extension();

						if (copy(from: $image['tmp_name'], to: $path)) {
							// Copied the product layer image into the product storage

							// Matching the product image with the product
							$layers[$layer]['image'] = $path;
						}
					}
				}
			}

			foreach ($products as $product) {
				// Iterating over products

				foreach ($product as $layer) {
					// Iterating over the product layer

					if (empty($layer['image'])) {
						// Found the empty layer

						// Exit (fail)
						return null;
					}
				}
			}

			if ($type === product_type::pin_37) {
				// Pin 37mm

				$biba = paper::generate(
					format: paper_format::a6,
					type: $type,
					products: $products,
					canvas: $canvas,
					dpi: 80,
					fit: true
				);
			}

			if (str_contains($this->request->headers['accept'], content::any->value)) {
				// Request for any response

				// Render page
				$page = $this->view->render('/generator/pin/page.html');

				// Sending response
				$this->response
					->start()
					->clean()
					->sse()
					->write($page)
					->validate($this->request)
					?->body()
					->end();

				// Deinitializing rendered page
				unset($page);

				// Exit (success)
				return null;
			}
		}

		// Exit (fail)
		return null;
	}
}
