<?php
/**
 * ReverseChargeSettings.php
 *
 * @since      1.0.0
 * @author     alfiopiccione <alfio.piccione@gmail.com>
 * @license    http://opensource.org/licenses/gpl-2.0.php GPL v2
 *
 * Copyright (C) 2025 POP
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

namespace WcElectronInvoice\WooCommerce\Fields;

if (! defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

final class ReverseChargeSettings
{
    /**
     * Return normalized shop country.
     *
     * @param string|null $country
     *
     * @return string
     */
    public static function getShopCountry(?string $country = null): string
    {
        if (null === $country) {
            $country = GeneralFields::getGeneralInvoiceOptionCountryState();
        }

        return strtoupper(trim((string) $country));
    }

    /**
     * Return whether the current shop uses the Poland KSeF contract.
     *
     * @param string|null $country
     *
     * @return bool
     */
    public static function isPolandShop(?string $country = null): bool
    {
        return 'PL' === self::getShopCountry($country);
    }

    /**
     * Return whether the shop uses select-based nature mappings.
     *
     * @param string|null $country
     *
     * @return bool
     */
    public static function usesStructuredNatureMappings(?string $country = null): bool
    {
        return in_array(self::getShopCountry($country), array('IT', 'SM', 'ES'), true);
    }

    /**
     * Return whether private reverse-charge mappings are relevant for the shop.
     *
     * @param string|null $country
     *
     * @return bool
     */
    public static function supportsPrivateMappings(?string $country = null): bool
    {
        return self::usesStructuredNatureMappings($country);
    }

    /**
     * Return whether reverse-charge normative reference should be used.
     *
     * @param string|null $country
     *
     * @return bool
     */
    public static function supportsNormativeReference(?string $country = null): bool
    {
        return ! self::isPolandShop($country);
    }

    /**
     * Return whether reverse-charge normative reference should be visible.
     *
     * @param string|null $country
     *
     * @return bool
     */
    public static function shouldDisplayRefNormRc(?string $country = null): bool
    {
        return self::supportsNormativeReference($country);
    }

    /**
     * Build settings fields for reverse-charge customer mappings.
     *
     * @param array       $natureOptions
     * @param array       $premiumCustomAttributes
     * @param string|null $country
     *
     * @return array
     */
    public static function getSettingsMappingFields(
        array $natureOptions,
        array $premiumCustomAttributes,
        ?string $country = null
    ): array {
        $shopCountry         = self::getShopCountry($country);
        $structuredMappings  = self::usesStructuredNatureMappings($shopCountry);
        $showPrivateMappings = self::supportsPrivateMappings($shopCountry);
        $showNormativeRef    = self::supportsNormativeReference($shopCountry);

        $fields = array();

        if ($showPrivateMappings) {
            $fields[] = self::buildNatureField('ue_private', $natureOptions, $premiumCustomAttributes, $shopCountry);
            if ($showNormativeRef) {
                $fields[] = self::buildNormativeField('ue_private', $premiumCustomAttributes, $shopCountry);
            }
        }

        $fields[] = self::buildNatureField('ue_company', $natureOptions, $premiumCustomAttributes, $shopCountry);
        if ($showNormativeRef) {
            $fields[] = self::buildNormativeField('ue_company', $premiumCustomAttributes, $shopCountry);
        }

        $fields[] = self::buildNatureField('ue_company_no_vies', $natureOptions, $premiumCustomAttributes, $shopCountry);
        if ($showNormativeRef) {
            $fields[] = self::buildNormativeField('ue_company_no_vies', $premiumCustomAttributes, $shopCountry);
        }

        if ($showPrivateMappings) {
            $fields[] = self::buildNatureField('extra_ue_private', $natureOptions, $premiumCustomAttributes, $shopCountry);
            if ($showNormativeRef) {
                $fields[] = self::buildNormativeField('extra_ue_private', $premiumCustomAttributes, $shopCountry);
            }
        }

        $fields[] = self::buildNatureField('extra_ue_company', $natureOptions, $premiumCustomAttributes, $shopCountry);
        if ($showNormativeRef) {
            $fields[] = self::buildNormativeField('extra_ue_company', $premiumCustomAttributes, $shopCountry);
        }

        return $fields;
    }

    /**
     * Build a nature-code field configuration.
     *
     * @param string $mappingType
     * @param array  $natureOptions
     * @param array  $premiumCustomAttributes
     * @param string $shopCountry
     *
     * @return array
     */
    private static function buildNatureField(
        string $mappingType,
        array $natureOptions,
        array $premiumCustomAttributes,
        string $shopCountry
    ): array {
        $structuredMappings = self::usesStructuredNatureMappings($shopCountry);

        $field = array(
            'id'                => 'wc_el_inv-' . $mappingType . '_nature_code',
            'type'              => $structuredMappings ? 'select' : 'text',
            'title'             => self::getMappingTitle($mappingType),
            'desc'              => sprintf('<small>%s</small>', self::getNatureDescription($mappingType, $shopCountry)),
            'default'           => '',
            'custom_attributes' => $premiumCustomAttributes,
        );

        if ($structuredMappings) {
            $field['options'] = ! empty($natureOptions) ? $natureOptions : array();
            $field['class']   = 'wc-enhanced-select rc-nature-select';
        } else {
            $field['placeholder'] = self::getNaturePlaceholder($mappingType, $shopCountry);
            $field['class']       = 'rc-nature-input';
        }

        return $field;
    }

    /**
     * Build a normative-reference field configuration.
     *
     * @param string $mappingType
     * @param array  $premiumCustomAttributes
     * @param string $shopCountry
     *
     * @return array
     */
    private static function buildNormativeField(
        string $mappingType,
        array $premiumCustomAttributes,
        string $shopCountry
    ): array {
        return array(
            'id'                => 'wc_el_inv-' . $mappingType . '_normative_reference',
            'type'              => 'text',
            'title'             => esc_html__('Tax rule reference:', WC_EL_INV_TEXTDOMAIN),
            'desc'              => sprintf('<small>%s</small>', self::getNormativeDescription($mappingType, $shopCountry)),
            'placeholder'       => esc_html__('Tax rule reference', WC_EL_INV_TEXTDOMAIN),
            'class'             => 'ref-nature',
            'default'           => '',
            'custom_attributes' => $premiumCustomAttributes,
        );
    }

    /**
     * Return label for the field title.
     *
     * @param string $mappingType
     *
     * @return string
     */
    private static function getMappingTitle(string $mappingType): string
    {
        switch ($mappingType) {
            case 'ue_private':
                return esc_html__('EU private customer:', WC_EL_INV_TEXTDOMAIN);
            case 'ue_company':
                return esc_html__('EU company (VIES valid):', WC_EL_INV_TEXTDOMAIN);
            case 'ue_company_no_vies':
                return esc_html__('EU company (VIES not valid):', WC_EL_INV_TEXTDOMAIN);
            case 'extra_ue_private':
                return esc_html__('Non-EU private customer:', WC_EL_INV_TEXTDOMAIN);
            case 'extra_ue_company':
                return esc_html__('Non-EU company:', WC_EL_INV_TEXTDOMAIN);
            default:
                return '';
        }
    }

    /**
     * Return nature field description.
     *
     * @param string $mappingType
     * @param string $shopCountry
     *
     * @return string
     */
    private static function getNatureDescription(string $mappingType, string $shopCountry): string
    {
        if (self::usesStructuredNatureMappings($shopCountry)) {
            switch ($mappingType) {
                case 'ue_private':
                    return esc_html__('Choose the tax treatment code used for EU private customers.', WC_EL_INV_TEXTDOMAIN);
                case 'ue_company':
                    return esc_html__('Choose the tax treatment code used for EU companies with VIES-valid VAT number.', WC_EL_INV_TEXTDOMAIN);
                case 'ue_company_no_vies':
                    return esc_html__('Choose the tax treatment code used for EU companies without VIES-valid VAT number.', WC_EL_INV_TEXTDOMAIN);
                case 'extra_ue_private':
                    return esc_html__('Choose the tax treatment code used for non-EU private customers.', WC_EL_INV_TEXTDOMAIN);
                case 'extra_ue_company':
                    return esc_html__('Choose the tax treatment code used for non-EU companies.', WC_EL_INV_TEXTDOMAIN);
            }
        }

        if (self::isPolandShop($shopCountry)) {
            switch ($mappingType) {
                case 'ue_company':
                case 'ue_company_no_vies':
                    return esc_html__('Accepted value: zero_wdt', WC_EL_INV_TEXTDOMAIN);
                case 'extra_ue_company':
                    return esc_html__('Accepted value: zero_export', WC_EL_INV_TEXTDOMAIN);
            }
        }

        return esc_html__('Enter the tax exemption code required by your invoicing channel for this customer type.', WC_EL_INV_TEXTDOMAIN);
    }

    /**
     * Return nature field placeholder.
     *
     * @param string $mappingType
     * @param string $shopCountry
     *
     * @return string
     */
    private static function getNaturePlaceholder(string $mappingType, string $shopCountry): string
    {
        if (self::isPolandShop($shopCountry)) {
            switch ($mappingType) {
                case 'ue_company':
                case 'ue_company_no_vies':
                    return 'zero_wdt';
                case 'extra_ue_company':
                    return 'zero_export';
            }
        }

        return esc_html__('Tax exemption code', WC_EL_INV_TEXTDOMAIN);
    }

    /**
     * Return normative-reference description.
     *
     * @param string $mappingType
     * @param string $shopCountry
     *
     * @return string
     */
    private static function getNormativeDescription(string $mappingType, string $shopCountry): string
    {
        if (self::usesStructuredNatureMappings($shopCountry)) {
            switch ($mappingType) {
                case 'ue_private':
                    return esc_html__('Enter the tax rule reference shown on the document for EU private customers.', WC_EL_INV_TEXTDOMAIN);
                case 'ue_company':
                    return esc_html__('Enter the tax rule reference shown on the document for EU companies with VIES-valid VAT number.', WC_EL_INV_TEXTDOMAIN);
                case 'ue_company_no_vies':
                    return esc_html__('Enter the tax rule reference shown on the document for EU companies without VIES-valid VAT number.', WC_EL_INV_TEXTDOMAIN);
                case 'extra_ue_private':
                    return esc_html__('Enter the tax rule reference shown on the document for non-EU private customers.', WC_EL_INV_TEXTDOMAIN);
                case 'extra_ue_company':
                    return esc_html__('Enter the tax rule reference shown on the document for non-EU companies.', WC_EL_INV_TEXTDOMAIN);
            }
        }

        return esc_html__('Enter the text shown on the document for this tax rule.', WC_EL_INV_TEXTDOMAIN);
    }
}
