<?php

namespace WKO\Controllers\Render;

use WKO\Controllers\Gateways\Credit;
use WKO\Controllers\Gateways\Gateway;
use WKO\Controllers\Render;
use WKO\Model\Repository\InstallmentRules;

/**
 * Render the credit checkout fields
 *
 * @package Controller\Render
 * @since 1.0.0
 */
class CreditCheckout extends Render
{

    public function get_installments($total = 0, $cardNumber = '', $cardBrand = '', $gateway = null)
    {
        if (!$gateway) {
            $gateway = new Credit;
        }

        $installments = $this->getDefaultInstallments($gateway, $total);

        $cartData = $this->getCartData($total);

        $repository = new InstallmentRules();
        $rules = $repository->getInstallmentRules($cardBrand, $cardNumber, $cartData);

        $hasOverrideRules = false;
        $overrideRuleInstallments = [];

        foreach ($rules as $rule) {
            if ($rule->overrideRules) {
                $hasOverrideRules = true;
                break;
            }
        }


        if ($hasOverrideRules) {
            $overrideRuleInstallments = [];
            foreach ($rules as $rule) {
                if ($rule->overrideRules) {
                    $ruleInstallments = $this->getCustomInstallments($rule, $gateway, $total);
                    $overrideRuleInstallments = array_replace_recursive($overrideRuleInstallments, $ruleInstallments);
                }
            }

            return $overrideRuleInstallments;
        } else {
            foreach ($rules as $rule) {
                $ruleInstallments = $this->getCustomInstallments($rule, $gateway, $total);
                $installments = array_replace_recursive($installments, $ruleInstallments);
            }

            return $installments;
        }
    }

    private function getDefaultInstallments($gateway, $total = 0)
    {
        $transferType = $gateway->get_option('rate_transfer_type');
        $transferSimple = $gateway->get_option('rate_transfer_simple');
        $transferInstallments = $gateway->get_option('rate_transfer_by_installments');
        $installments = $this->getInstallmentsFee($transferType, $transferSimple, $transferInstallments);

        $orderTotal  = !$total ? WC()->cart->total : $total;

        $maxInstallments = (int) $gateway->get_option('installments');

        foreach ($installments as $key => $value) {
            if ($key <= $maxInstallments) {
                $amount = 0;

                if ($gateway->get_option('rate_transfer_format') == 1) {
                    $amount = ($value / 100) * $orderTotal;
                }

                if ($gateway->get_option('rate_transfer_format') == 2) {
                    $amount = $value;
                }

                $total = $orderTotal + $amount;

                $arr[$key] = $this->getInstallmentText($key, $total, $amount, $gateway);
            }
        }

        return $arr;
    }

    private function getCustomInstallments($rule, $gateway, $total = 0)
    {
        $installments = $this->getInstallmentsFee($rule->rateTransferType, $rule->rateTransferSimple, $rule->rateTransferByInstallments);

        $orderTotal  = !$total ? WC()->cart->total : $total;

        $maxInstallments = $rule->maxInstallments;
        $minInstallments = $rule->minInstallments;
        $minInstallmentValue = $rule->minInstallmentValue;

        $arr = [];
        foreach ($installments as $key => $value) {
            if ($key >= $minInstallments && $key <= $maxInstallments) {
                $amount = 0;

                if ($rule->rateTransferFormat == 1) {
                    $amount = ($value / 100) * $orderTotal;
                }

                if ($rule->rateTransferFormat == 2) {
                    $amount = $value;
                }

                $totalWithAmount = $orderTotal + $amount;
                $installmentValue = $totalWithAmount / $key;

                if ($installmentValue >= $minInstallmentValue) {
                    $arr[$key] = $this->getInstallmentText($key, $totalWithAmount, $amount, $gateway, $rule);
                }
            }
        }

        return $arr;
    }

    private function getInstallmentText($installment, $total, $rate, $gateway, $rule = null)
    {
        $value = number_format(($total / $installment), 2, '.', '');
        $total = number_format($total, 2, '.', '');
        $rateText = __('Interest-free', 'wc-koin-official');

        if ($rate > 0) {
            $rateText = __('With interest', 'wc-koin-official');
        }
        $currency = html_entity_decode(get_woocommerce_currency_symbol(), ENT_QUOTES, 'UTF-8');

        $format = $gateway->get_option('installments_show_mode');
        switch ($format) {
            case 'price_text':
                $text = "$installment x $currency$value - $rateText";
                break;
            case 'price_total':
                $text = "$installment x $currency$value ($currency$total)";
                break;
            case 'price_total_text':
                $text = "$installment x $currency$value ($currency$total) - $rateText";
                break;
            default:
                $text = "$installment x $currency" . $value;
                break;
        }

        if ($rule && isset($rule->installmentDisplay) && !empty($rule->installmentDisplay)) {
            $customFormatText = $rule->installmentDisplay;
            $text = $customFormatText . ' - ' . $text;
        }

        return $text;
    }

    private function getInstallmentsFee($rateType, $rateTransferSimple = 0, $rateTransferInstallments = ''): array
    {
        $rates = [];
        for ($i = 1; $i <= 72; $i++) {
            $rates[$i] = '0.00';
        }

        if ($rateType == 1) {
            for ($i = 1; $i <= 72; $i++) {
                $rates[$i] = floatval($rateTransferSimple);
            }
        }

        if ($rateType == 2) {
            $customRates = json_decode($rateTransferInstallments, true);
            if (is_array($customRates)) {
                foreach ($customRates as $i => $v) {
                    if ($i >= 1 && $i <= 72) {
                        $rates[$i] = $v;
                    }
                }
            }
        }

        return $rates;
    }

    /**
     * Get cart/order data for filtering installment rules
     *
     * @param float $total Optional total value to determine if it's from an order
     * @return array Cart data with product_ids, brand_ids, and category_ids
     */
    private function getCartData($total = 0): array
    {
        $productIds = [];
        $brandIds = [];
        $categoryIds = [];
        wc_load_cart();

        if (WC()->cart && !WC()->cart->is_empty()) {
            foreach (WC()->cart->get_cart() as $cartItem) {
                $product = $cartItem['data'];
                if ($product) {
                    $productId = $product->get_parent_id() == 0 ? $product->get_id() : $product->get_parent_id();
                    $productIds[] = $productId;

                    $categories = wc_get_product_term_ids($productId, 'product_cat');
                    $categoryIds = array_merge($categoryIds, $categories);

                    if (taxonomy_exists('product_brand')) {
                        $brands = wc_get_product_term_ids($productId, 'product_brand');
                        $brandIds = array_merge($brandIds, $brands);
                    }
                }
            }
        }

        return [
            'product_ids' => array_unique($productIds),
            'brand_ids' => array_unique($brandIds),
            'category_ids' => array_unique($categoryIds),
        ];
    }

    private function get_hash()
    {
        return get_option('wc_koin_settings_secret_key');
    }

    public function get_org_id()
    {
        return get_option('wc_koin_settings_org_id');
    }

    public function request()
    {
        global $woocommerce;
        $hash = base64_encode($this->get_hash());

        $orderId = filter_input(INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT) ?? absint(get_query_var('order-pay'));
        $order = wc_get_order($orderId);
        $price = (float) $woocommerce->cart->total;

        if ($order) {
            $price = (float) $order->get_total();
        }

        $this->render('templates/checkout/credit.php', [
            'installments' => [],
            'hash'         => $hash,
            'mode'         => get_option('wc_koin_settings_environment'),
            'org_id'       => $this->get_org_id(),
            'price'        => $price,
        ]);
    }
}
