<?php

namespace AcceptBlue\Level3;

class WCLineItems
{
    private \WC_Order $order;
    private int $lineItemsCount = 0;
    private array $lineItems;
    private int $currentLineItem = 0;
    private array $coupons;
    private string $unitOfMeasure = 'EA';

    public function __construct(\WC_Order $order)
    {
        $this->order = $order;
        $this->lineItems = array_values($this->order->get_items());
        $this->lineItemsCount = count($this->lineItems);
        $this->coupons = $this->order->get_coupons();
    }

    public function hasLineItems(): bool
    {
        return $this->lineItemsCount > 0;
    }

    public function hasNext(): bool
    {
        $hasNext = $this->currentLineItem < $this->lineItemsCount;

        if (!$hasNext) {
            $this->currentLineItem = 0;
        }

        return $hasNext;
    }

    public function next(): void
    {
        $this->currentLineItem++;
    }

    public function getName(){
        return $this->getCurrent()->get_name();
    }

    public function getSku()
    {
        $product = $this->getCurrent()->get_product();
        return ($product) ? $product->get_sku() : '';
    }

    public function getDescription(): string
    {
        $product = $this->getCurrent()->get_product();
        return ($product) ? $product->get_description() : '';
    }

    public function getCost(): float
    {
        $total = (float)$this->getCurrent()->get_total();
        $quantity = (float)$this->getCurrent()->get_quantity();
        return $total / $quantity;
    }

    public function getQuantity()
    {
        return $this->getCurrent()->get_quantity();
    }

    public function getTaxAmount(): float
    {
        return (float)$this->getCurrent()->get_total_tax();
    }

//    public function getCouponsDiscountAmount(): float {
//        return (float)$this->getCouponsTotalProductDiscount($this->getCurrent());
//    }

    public function getAllFields(): array
    {
        $fields = array();
        if ($this->hasLineItems()) {
            while ($this->hasNext()) {
                $fields[] = (object)[
                    'name' => wp_html_excerpt($this->getName(), 50, '...'),
                    'sku' => $this->getSku(),
                    'description' => wp_html_excerpt($this->getDescription(), 200, '...'),
                    'cost' => $this->getCost(),
                    'quantity' => $this->getQuantity(),
                    'tax_amount' => $this->getTaxAmount(),
                    'unit_of_measure' => $this->unitOfMeasure,
//                    'discount_amount' => $this->getCouponsTotalProductDiscount($this->getCurrent())
                ];

                $this->next();
            }
        }

        return $fields;
    }

    private function getCurrent()
    {
        return $this->lineItems[$this->currentLineItem];
    }

    private function getCouponsTotalProductDiscount(\WC_Order_Item $current): float {
        $total_discount = 0;
        $product = $current->get_product();

        if(!$product) {
            return $total_discount;
        }

        foreach ($this->coupons as $coupon_item) {
            $coupon = new \WC_Coupon($coupon_item->get_code());

            if (!$this->isCouponApplicableToProduct($coupon, $product)) {
                continue;
            }

            $discount = $coupon->get_discount_amount($product->get_price(), $this->getCurrent(), false);

            if ($discount > 0) {
                $total_discount += $discount;
            }
        }

        return $total_discount;
    }

    private function isCouponApplicableToProduct($coupon, $product): bool
    {
        $discount_type = $coupon->get_discount_type();
        $product_id = $product->get_id();

        if (in_array($discount_type, ['fixed_cart', 'percent'])) {
            return true;
        }

        if (in_array($discount_type, ['fixed_product', 'percent_product'])) {
            $product_ids = $coupon->get_product_ids();
            $excluded_ids = $coupon->get_excluded_product_ids();
            $category_ids = $coupon->get_product_categories();
            $excluded_categories = $coupon->get_excluded_product_categories();

            if (in_array($product_id, $excluded_ids)) {
                return false;
            }

            if (!empty($product_ids) && !in_array($product_id, $product_ids)) {
                return false;
            }

            $product_categories = wp_get_post_terms($product_id, 'product_cat', ['fields' => 'ids']);

            if (!empty($excluded_categories) && array_intersect($product_categories, $excluded_categories)) {
                return false;
            }

            if (!empty($category_ids) && !array_intersect($product_categories, $category_ids)) {
                return false;
            }

            return true;
        }

        return false;
    }
}