<?php

namespace endpoints\orders;

use classes\economic;
use Exception;
use traits\economic_endpoint_t;

class economic_invoices_drafts_endpoint
{
    use economic_endpoint_t;

    private static function apply_url_params(array $params): string
    {
        // Check if the params are empty,
        // if so, return an empty string
        if (empty($params)) {
            return '';
        }

        /**
         * Define the prefix for the new query string,
         * this is used to determine if the query string
         * should start with a ? or & (e.g. ?filter= or &filter=)
         * Depending on the first character of the query string
         * @param string $additionUrlString
         * @return string
         */
        function definePrefix(string $additionUrlString): string
        {
            // Check if the string is empty
            return (empty($additionUrlString) ? '?' : '&');
        }

        $url = '';
        if (isset($params['filters'])) {
            $url .= definePrefix($url) . 'filter=' . self::filters($params['filters']);
        }
        if (isset($params['pagination'])) {
            $url .= definePrefix($url) . self::pagination($params['pagination']);
        }
        echo 'URL: ' . $url . PHP_EOL;
        return $url;
    }

    /**
     * List draft invoices
     * @param array $filters
     * @param array $pagination
     * @return object {collection: [order], pagination: {maxPageSize: number, skipPages: number, results: number}}
     */
    public function get(array $filters = [], array $pagination = []): object
    {
        $response = $this->send_request(
            '/invoices/drafts/?filter=' . self::filters($filters) . self::pagination($pagination),
            'GET'
        );
        // Return the response as an object
        return json_decode($response);
    }

    /**
     * List ALL draft invoices
     * This will get all draft invoices, on all pages
     * @return object {collection: [order]}
     */
    public function get_all(): object
    {
        $response = $this->send_request(
            '/invoices/drafts/' . self::pagination([
                'maxPageSize' => 1000,
                'skipPages' => 0,
            ]),
            'GET',
        );
        // Return the response as an object
        return json_decode($response);
    }

    /**
     * Get invoice lines
     * @param array $invoice_ids List of invoice ids to get lines for (e.g. [1, 2, 3])
     * @param array $filters Set the filter using the self::filter method
     * @return array {invoice_id: {collection: [invoice_line], pagination: {maxPageSize: number, skipPages: number, results: number}}}
     */
    public function get_invoice_lines(array $invoice_ids, array $filters = []): array
    {
        $tmp_invoices = [];
        foreach ( $invoice_ids as $invoice ) {
            $response = $this->send_request(
                '/invoices/drafts/' . $invoice . '/?filter=' . self::filters($filters),
                'GET'
            );
            $tmp_invoices[$invoice] = json_decode($response)->lines;
        }
        return $tmp_invoices;
    }

    /**
     * Add a new invoice
     * @param int $customer_number The E-conomic customer number
     * @param string $external_id The external id of the invoice
     * @param string|null $date The date of the invoice (YYYY-MM-DD)
     * @return object {id: number, getExternalId: string}
     * @throws Exception If the request fails
     */
    public function add(int $customer_number, string $external_id = '', string|null $date = null): object
    {
        // Get the layout number
        $layout_number = (int)(new economic())->config->invoice_layout->getVariableValue();

        // Check if the date is set
        if (is_null($date)) {
            // Get the date
            $date = date('Y-m-d');
        } else {
            // Check if the date is valid
            if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
                throw new Exception('Invalid date format. Use YYYY-MM-DD.');
            }
        }
        // Get the customer object
        $customer = (new economic())->getCustomer($customer_number);

        // Set the recipient details
        $customer_name = $customer->getName() ?? 'Ukendt';
        $customer_address = $customer->getAddress() ?? 'Ukendt';
        $customer_zip = $customer->getZipCode() ?? 'Ukendt';
        $customer_city = $customer->getCity() ?? 'Ukendt';

        // Send the request
        $response = $this->send_request(
            '/invoices/drafts/',
            'POST',
            json_encode([
                // Set the layout number (This is defined in the E-conomic module settings)
                'layout' => [
                    'layoutNumber' => $layout_number
                ],

                // Set the date to today
                'date' => $date,

                // Set the payment terms to the default payment terms (This is defined in the E-conomic module settings)
                'paymentTerms' => [
                    'paymentTermsNumber' => (int)$customer->getPaymentTermsNumber(),
                ],

                // Set the vat zone (This is defined in the E-conomic module settings)
                'vatZone' => [
                    'vatZoneNumber' => (int)$customer->getVatZoneNumber(),
                ],

                // Set the customer number
                'customer' => [
                    'customerNumber' => $customer_number
                ],

                // Set the external id (This is used to link the invoice to the collected order invoice)
                'references' => [
                    'other' => $external_id
                ],

                // Set the currency
                'currency' => $customer->getCurrency() ?? 'DKK',

                // Set the recipient details
                'recipient' => [
                    'name' => $customer_name,
                    'address' => $customer_address,
                    'zip' => $customer_zip,
                    'city' => $customer_city,
                    'vatZone' => [
                        'vatZoneNumber' => (int)$customer->getVatZoneNumber(),
                    ],
                ],
            ])
        );
        // Return the response as an object
        return json_decode($response);
    }

    public function exists(int $draft_invoice_number): bool
    {
        $response = $this->send_request(
            '/invoices/drafts/' . $draft_invoice_number,
            'GET'
        );
        // Return the response as an object
        try {
            return json_decode($response)->draftInvoiceNumber == $draft_invoice_number;
        } catch (Exception $e) {
            return false;
        }
    }

}