<?php declare(strict_types=1);

namespace App\Services\Api\V1;

use App\Captcha\Contracts\ImageBody;
use App\Captcha\Contracts\ImageHead;
use App\Captcha\Contracts\Type;
use App\ServiceResults\Api\V1\CaptchaGenerateService\Captcha;
use App\ServiceResults\ServiceResultError;
use App\Services\Service;
use Illuminate\Support\Arr;
use App\Captcha\Config\ImageHead as ImageHeadConfig;
use App\Captcha\Config\ImageBody as ImageBodyConfig;

final class CaptchaGenerateService extends Service
{
    public function __construct(
        private readonly array $config,
        private readonly ImageHead $imageHead,
        private readonly ImageBody $imageBody
    ) { }

    public function generate(): ServiceResultError | Captcha
    {
        $types = $this->config['types'] ?? [];
        if (empty($types)) {
            $error = __('No captcha type settings!');
            report($error);
            return $this->errService($error);
        }

        try {
            $type = Arr::random($types);

            /** @var Type $captcha */
            $typeCaptcha = new $type['class'](
                $type['params'] ?? []
            );
            $symbols = $typeCaptcha->getSymbols();

            $imageHeadConfig = $this->makeImageHeadConfig($this->config['image_head'] ?? []);
            $imageHead = $this->imageHead->processing($symbols, $imageHeadConfig);
            unset($imageHeadConfig);

            $imageBodyConfig = $this->makeImageBodyConfig($this->config['image_body'] ?? []);
            $imageBody = $this->imageBody->processing($symbols, $imageBodyConfig);
            unset($imageBodyConfig);
        } catch (\Throwable $e) {
            report($e);
            return $this->errService('Captcha service error!');
        }

        return new Captcha(
            imageHead: $imageHead,
            imageBody: $imageBody
        );
    }

    private function makeImageHeadConfig(array $params): ImageHeadConfig
    {
        return new ImageHeadConfig(
            backgrounds: $params['backgrounds'] ?? [],
            fonts: $params['fonts'] ?? [],
            fontColors: $params['font_colors'] ?? [],
            width: $params['width'] ?? 150,
            height: $params['height'] ?? 40,
            textPaddingTop: $params['text_padding_top'] ?? 5,
            textPaddingLeft: $params['text_padding_left'] ?? 10,
            angle: $params['angle'] ?? 20,
            numberLines: $params['number_lines'] ?? 3,
            lineColors: $params['line_colors'] ?? []
        );
    }

    private function makeImageBodyConfig(array $params): ImageBodyConfig
    {
        return new ImageBodyConfig(
            backgrounds: $params['backgrounds'] ?? [],
            fonts: $params['fonts'] ?? [],
            fontColors: $params['font_colors'] ?? [],
            width: $params['width'] ?? 300,
            height: $params['height'] ?? 240,
            angle: $params['angle'] ?? 20,
            fontSize: $params['font_size'] ?? [20, 50],
            numberLines: $params['number_lines'] ?? 3,
            lineColors: $params['line_colors'] ?? []
        );
    }
}
