<?php

namespace WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\Creators;

use Exception;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesAbstracts\Containers\MetaContainer;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesAbstracts\Documents\Document;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesAbstracts\Documents\DocumentGetters;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\Data\DataSourceFactory;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\Documents\AbstractDocument;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\DocumentsMeta\CustomMeta;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\DocumentsMeta\NullCustomMeta;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\Email\DocumentEmail;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\Helpers\BlockTemplateEditor;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\Integration\DocumentNumbers\BlockTemplateDocumentNumber;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\Integration\DocumentNumbers\DocumentNumber;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\BlockEditor\BlockTemplate\BlockTemplate;
use WPDeskFIVendor\WPDesk\Library\FlexibleInvoicesCore\Settings\Settings;
/**
 * Abstract document creator.
 *
 * @package WPDesk\Library\FlexibleInvoicesCore\Creators
 */
abstract class AbstractDocumentCreator implements Creator
{
    const TYPE = 'invoice';
    /**
     * @var string
     */
    protected $button_label;
    /**
     * @var string
     */
    protected $name;
    /**
     * @var Document
     */
    protected $document;
    /**
     * @var DataSourceFactory
     */
    protected $source_factory;
    /**
     * @var int
     */
    protected $order_id;
    /**
     * @param DataSourceFactory $source_factory
     * @param string            $button_label
     * @param string            $name
     */
    public function __construct(DataSourceFactory $source_factory, string $button_label, string $name)
    {
        $this->button_label = $button_label;
        $this->name = $name;
        $this->source_factory = $source_factory;
    }
    /**
     * @param int $order_id
     */
    public function set_order_id(int $order_id)
    {
        $this->order_id = $order_id;
    }
    /**
     * @return string
     */
    public function get_type(): string
    {
        return self::TYPE;
    }
    /**
     * @return string
     */
    public function get_button_label(): string
    {
        return $this->button_label;
    }
    /**
     * @return string
     */
    public function get_name(): string
    {
        return $this->name;
    }
    /**
     * @return Document
     */
    public function get_document(): Document
    {
        return $this->document;
    }
    /**
     * @return bool
     */
    public function is_allowed_for_create(): bool
    {
        return \true;
    }
    /**
     * @return bool
     */
    public function is_allowed_for_auto_create(): bool
    {
        return \true;
    }
    /**
     * @return DocumentEmail
     */
    abstract public function get_email_class();
    /**
     * @return bool
     */
    public function is_allowed_to_send(): bool
    {
        return \true;
    }
    /**
     * @return bool
     */
    public function is_allowed_for_edit(): bool
    {
        return \true;
    }
    /**
     * @param AbstractDocument $document
     *
     * @return DocumentNumber
     */
    public function get_document_numbering(Document $document): DocumentNumber
    {
        if (BlockTemplateEditor::is_block_template_editor_active()) {
            $block_template = new BlockTemplate($document->get_template_id());
            return new BlockTemplateDocumentNumber($this->source_factory->get_settings(), $document, $block_template, $this->get_name());
        }
        return new DocumentNumber($this->source_factory->get_settings(), $document, $this->get_name());
    }
    /**
     * @return bool
     */
    public function can_show_document_in_my_account(): bool
    {
        return \true;
    }
    /**
     * @param AbstractDocument $document
     * @param int             $post_id
     * @param string          $source_type
     *
     * @throws Exception
     */
    protected function assign_data_from_source(Document $document, int $post_id, string $source_type)
    {
        $data = $this->source_factory->get_source($post_id, $source_type, $this->get_type());
        $document->set_number($data->get_number());
        $document->set_formatted_number($data->get_formatted_number());
        $document->set_date_of_pay($data->get_date_of_pay());
        $document->set_date_of_paid($data->get_date_of_paid());
        $document->set_date_of_issue($data->get_date_of_issue());
        $document->set_date_of_sale($data->get_date_of_sale());
        $document->set_customer($data->get_customer());
        $document->set_recipient($data->get_recipient());
        $document->set_customer_filter_field($data->get_customer_filter_field());
        $document->set_seller($data->get_seller());
        $document->set_currency($data->get_currency());
        $document->set_discount($data->get_discount());
        $document->set_id($data->get_id());
        $document->set_items($data->get_items());
        $document->set_payment_method($data->get_payment_method());
        $document->set_payment_method_name($data->get_payment_method_name());
        $document->set_payment_status($data->get_payment_status());
        $document->set_notes($data->get_notes());
        $document->set_tax((string) $data->get_tax());
        $document->set_total_gross($data->get_total_gross());
        $document->set_total_net($data->get_total_net());
        $document->set_total_paid($data->get_total_paid());
        $document->set_total_gross($data->get_total_gross());
        $document->set_total_tax($data->get_total_tax());
        $document->set_user_lang($data->get_user_lang());
        $document->set_show_order_number($data->get_show_order_number());
        $document->set_order_id($data->get_order_id());
        $document->set_corrected_id($data->get_corrected_id());
        $document->set_template_id($data->get_template_id());
        $this->document = $document;
    }
    /**
     * @param DocumentGetters $document
     * @param MetaContainer   $meta
     *
     * @return CustomMeta
     */
    public function custom_meta(DocumentGetters $document, MetaContainer $meta)
    {
        return new NullCustomMeta($document, $meta);
    }
    /**
     * @return array
     */
    public function get_auto_create_statuses(): array
    {
        $settings = new Settings();
        $status = $settings->get($this->get_type() . '_auto_create_status', []);
        if (is_string($status) && !empty($status)) {
            return [$status];
        }
        if (is_array($status)) {
            //@phpstan-ignore-line
            return $status;
        }
        return [];
    }
}
