<?php

declare(strict_types=1);

namespace Gls\GlsPoland\AdePlus\Printout;

final class LabelsPrintMode implements PrintModeInterface, \Stringable
{
    public const PDF_A4_TOP_LEFT = 'one_label_on_a4_lt_pdf';
    public const PDF_A4_TOP_RIGHT = 'one_label_on_a4_rt_pdf';
    public const PDF_A4_BOTTOM_LEFT = 'one_label_on_a4_lb_pdf';
    public const PDF_A4_BOTTOM_RIGHT = 'one_label_on_a4_rb_pdf';
    public const PDF_A4_CENTER = 'one_label_on_a4_pdf';
    public const PDF_A4_FOUR_FROM_LEFT = 'four_labels_on_a4_pdf';
    public const PDF_A4_FOUR_FROM_RIGHT = 'four_labels_on_a4_right_pdf';
    public const PDF_ROLL_HORIZONTAL = 'roll_160x100_pdf';
    public const PDF_ROLL_VERTICAL = 'roll_160x100_vertical_pdf';
    public const DPL_ROLL = 'roll_160x100_datamax';
    public const ZPL_ROLL = 'roll_160x100_zebra';
    public const ZPL_ROLL_300_DPI = 'roll_160x100_zebra_300';
    public const EPL_ROLL = 'roll_160x100_zebra_epl';

    public const PRINT_MODES = [
        self::PDF_A4_TOP_LEFT,
        self::PDF_A4_TOP_RIGHT,
        self::PDF_A4_BOTTOM_LEFT,
        self::PDF_A4_BOTTOM_RIGHT,
        self::PDF_A4_CENTER,
        self::PDF_A4_FOUR_FROM_LEFT,
        self::PDF_A4_FOUR_FROM_RIGHT,
        self::PDF_ROLL_HORIZONTAL,
        self::PDF_ROLL_VERTICAL,
        self::DPL_ROLL,
        self::ZPL_ROLL,
        self::ZPL_ROLL_300_DPI,
        self::EPL_ROLL,
    ];

    private $mode;

    private function __construct(string $printMode)
    {
        $this->mode = $printMode;
    }

    public static function from(string $printMode): self
    {
        if (!in_array($printMode, self::PRINT_MODES, true)) {
            throw new \InvalidArgumentException(sprintf('Unrecognized label type "%s".', $printMode));
        }

        return new self($printMode);
    }

    public static function tryFrom($value): ?self
    {
        if (!in_array($value, self::PRINT_MODES, true)) {
            return null;
        }

        return new self($value);
    }

    public function __toString(): string
    {
        return $this->mode;
    }

    public function getContentType(): string
    {
        switch ($this->mode) {
            case self::DPL_ROLL:
                return 'application/dpl';
            case self::ZPL_ROLL:
            case self::ZPL_ROLL_300_DPI:
                return 'application/zpl';
            case self::EPL_ROLL:
                return 'application/epl2';
            default:
                return 'application/pdf';
        }
    }

    public function getFileExtension(): string
    {
        switch ($this->mode) {
            case self::DPL_ROLL:
                return 'dpl';
            case self::ZPL_ROLL:
            case self::ZPL_ROLL_300_DPI:
                return 'zpl';
            case self::EPL_ROLL:
                return 'epl2';
            default:
                return 'pdf';
        }
    }
}
