<?php

namespace App;

use Mtc\Shop\Item as ShopItem;
use Illuminate\Support\Collection;
use Mtc\Shop\Assessment\Assessment;
use Mtc\Modules\Members\Classes\Auth;
use Mtc\Plugins\Upsells\Classes\Upsells;
use MtcPharmacy\Bundles\Classes\Bundle;
use MtcPharmacy\Bundles\Classes\BundleType;
use MtcPharmacy\Subscriptions\Classes\Subscription;
use MtcPharmacy\Subscriptions\Classes\SubscriptionPreference;


class ShopHelper
{
    private static function getDefaultSubscriptionPeriods()
    {
        return [
            7 => '1 week',
            14 => '2 weeks',
            21 => '3 weeks',
            28 => '4 weeks',
            30 => '1 month',
            42 => '6 weeks',
            60 => '2 months',
            90 => '3 months',
            180 => '6 months',
        ];
    }

    public static function getAllowedSubscriptionPeriods(ShopItem $item)
    {
        $allowed_periods = [];

        $sub_config = SubscriptionPreference::init($item->id);
        if ($sub_config) {
            $min_days = $sub_config->getIntervalApproximateEquivalentInDays();
        } else {
            $min_days = 7;
        }

        $default_periods = self::getDefaultSubscriptionPeriods();
        foreach ($default_periods as $temp_period_days => $temp_period_text) {
            if ($temp_period_days >= $min_days) {
                $allowed_periods[] = $temp_period_text;
            }
        }

        return $allowed_periods;
    }

    public static function hasCustomerSubscriptionToBundleType(BundleType $bundle_type)
    {
        $has_subscription = false;

        $customer = Auth::getLoggedInMember();

        if ($customer) {
            $subscriptions = Subscription::query()
                ->where('member_id', $customer->id)
                ->get()
            ;

            foreach ($subscriptions as $subscription) {
                $sbt = SubscriptionBundleType::query()
                    ->where('subscription_id', $subscription->id)
                    ->first()
                ;

                if ($sbt->bundletype_id == $bundle_type->id && SubscriptionBundleType::isSubscriptionEditable($subscription)) {
                    $has_subscription = true;
                    break;
                }
            }
        }

        return $has_subscription;
    }


    public static function forgetNotAllowed(Collection $products, Assessment $a)
    {
        $weight_kg = $a->getWeight(60);
        $age = $a->getAge(40);

        foreach ($products as $key => $product) {
            $product_group = new ProductGroup($product);
            switch ($product_group->getName()) {
                case ProductGroup::GROUP_A:
                    //Atovaquone/Proguanil 250/125mg – greater than or equal to 40kg: one daily starting 2 days before, whilst away and 7 days on return.
                    //Calculation: number of risk days + 9 tablets
                    //Products: Malarone, Maloff and Generic Malarone

                    if ((int) $weight_kg < 40) {
                        $products->forget($key);
                    }
                    break;

                case ProductGroup::GROUP_AP:
                    //Atovaquone/Proguail Paediatric 62.5/25mg – same as above but number taken each day depends on weight.
                    //Calculation.  10-19.9kg: 1 daily | 20-29.9kg: 2 daily | 30-39.9kg: 3 daily | 40kg and over they need adult (see above).
                    //Products: Malarone Paediatric and Atovaquone Proguanil 62.5/25mg
                    if ((int) $weight_kg < 10 || (int) $weight_kg >= 40) {
                        $products->forget($key);
                    }
                    break;

                case ProductGroup::GROUP_L:
                    if ((int) $weight_kg < 6) {
                        $products->forget($key);
                    }
                    break;

                case ProductGroup::GROUP_D:
                    // Doxy - 12 years or older
                    if ((int) $age < 12) {
                        $products->forget($key);
                    }
                    break;
            }
        }
    }


    /**
     * Attach the eligible upsell products for each product as a `upsells` array,
     * shaped for the assessment "Complete your basket" overlay. No-op when the
     * Upsells plugin is disabled. Eligibility is resolved live in
     * getUpsellsForCollection().
     */
    public static function decorateWithUpsells(Collection $products)
    {
        if (!config('upsells.enabled')) {
            return;
        }

        // Batch-resolve upsells for the whole collection (two queries) rather than
        // querying per product in the loop.
        $upsells_by_item = self::resolveUpsells($products);

        self::applyUpsells($products, $upsells_by_item);
    }

    /**
     * Resolve the `item_id => upsell rows` map for a product set in a fixed two
     * queries. Returns an empty map when the Upsells plugin is disabled, so
     * callers can resolve once and apply across several collections.
     *
     * @return array<int, array<int, array>> Map from item_id to overlay-shaped upsell rows
     */
    public static function resolveUpsells($products): array
    {
        if (!config('upsells.enabled')) {
            return [];
        }

        return Upsells::getUpsellsForCollection($products);
    }

    /**
     * Attach a pre-resolved `item_id => upsell rows` map onto each product as an
     * `upsells` array. No queries — use when the same product set is decorated
     * across several collections (e.g. per-patient groups) so the upsell lookup
     * runs once rather than once per group.
     *
     * @param array<int, array<int, array>> $upsells_by_item Map from resolveUpsells()
     */
    public static function applyUpsells(Collection $products, array $upsells_by_item)
    {
        foreach ($products as $product) {
            $product->upsells = $upsells_by_item[$product->id] ?? [];
        }
    }


    public static function decorateWithMinimumQuantity(Collection $products, Assessment $a)
    {
        $assessment_weight = $a->getWeight(60);

        $days_away = (int) $a->getAdditionalInfoValue('trip_duration_days');

        foreach ($products as $temp_product) {
            $temp_product->minimum_quantity = self::getMinimumQuantity(
                $temp_product,
                $assessment_weight,
                $days_away
            );
        }
    }


    public static function getMinimumQuantity(ShopItem $product, int $weight_kg = null, $days_away = null): int
    {
        $min_qty = 1;

        if ($weight_kg && $days_away) {
            $product_group = new ProductGroup($product);
            switch ($product_group->getName()) {
                //Atovaquone/Proguail Paediatric 62.5/25mg – same as above but number taken each day depends on weight.
                //Calculation.  10-19.9kg: 1 daily | 20-29.9kg: 2 daily | 30-39.9kg: 3 daily | 40kg and over they need adult (see above).
                //Products: Malarone Paediatric and Atovaquone Proguanil 62.5/25mg
                case ProductGroup::GROUP_AP:
                    if ($weight_kg < 10) {
                        $min_qty = 0;
                    } elseif ($weight_kg < 20) {
                        $min_qty = (2 + $days_away + 7);
                    } elseif ($weight_kg < 30) {
                        $min_qty = (2 + $days_away + 7) * 2;
                    } elseif ($weight_kg < 40) {
                        $min_qty = (2 + $days_away + 7) * 3;
                    } else {
                        $min_qty = 0;
                    }
                    break;

                //Atovaquone/Proguanil 250/125mg – greater than or equal to 40kg: one daily starting 2 days before, whilst away and 7 days on return.
                //Calculation: number of risk days + 9 tablets
                //Products: Malarone, Maloff and Generic Malarone
                case ProductGroup::GROUP_A:
                    if ($weight_kg < 40) {
                        $min_qty = 0;
                    } else {
                        $min_qty = 2 + $days_away + 7;
                    }
                    break;

                //Doxycycline: one daily starting 2 days before, whilst there and 28 days on return
                //Calculation: days away + 30 capsules
                case ProductGroup::GROUP_D:
                    $min_qty = $days_away + 2 + 28;
                    break;

                //Lariam (Mefloquine) – one weekly starting 10 days before arrival, whilst away and 4 week son return
                //Calculation:  (10 + days away + 28) / 7
                case ProductGroup::GROUP_L:
                    if ($weight_kg < 6) {
                        $lariam_multiplier = 0;
                    } elseif ($weight_kg < 16) {
                        $lariam_multiplier = 0.25;
                    } elseif ($weight_kg < 25) {
                        $lariam_multiplier = 0.5;
                    } elseif ($weight_kg < 45) {
                        $lariam_multiplier = 0.75;
                    } else {
                        $lariam_multiplier = 1;
                    }

                    $min_qty = (10 + $days_away + 28) / 7;
                    $min_qty *= $lariam_multiplier;
                    $min_qty = ceil($min_qty);

                    break;
            }
        }

        return $min_qty;
    }

}
