<?php

namespace Hilco\Models;

use Auth;
use Carbon\Carbon;
use DB;
use Debugbar;
use Exception;
use HilcoB2B\M3Request;
use Hilco\GuzzleWrappers\APIGuzzleWrapper;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Klaviyo\Klaviyo;
use Klaviyo\Model\EventModel as KlaviyoEvent;
use Log;

class SubscriptionGroup extends UuidModel
{
    protected $table = 'SubscriptionGroups';
    protected $fillable = ['subscriptiongroup_type'];


    public function soldToCustomer() {
        return $this->hasOne(Customer::class, 'id', 'soldto_customer_id');
    }

    public function billToCustomer() {
        return $this->hasOne(Customer::class, 'id', 'billto_customer_id');
    }

    public function customerShippingAddress() {
        return $this->hasOne(CustomerShippingAddress::class, 'id', 'customershippingaddress_id');
    }

    public function createdByWebUser() {
        return $this->hasOne(WebUser::class, 'id', 'createdby_webuser_id');
    }
    public function modifiedByWebUser() {
        return $this->hasOne(WebUser::class, 'id', 'lastmodifiedby_webuser_id');
    }

    public function subscriptionItems() {
        return $this->hasMany(SubscriptionItem::class, 'subscriptiongroup_id', 'id');
    }

    public function subscriptionPeriod() {
        return $this->hasOne(SubscriptionPeriod::class, 'id', 'subscriptionperiod_id');
    }

    public static function sendKlaviyoEventForSubscriptionGroup($eventName, $subscriptionGroup, $cartStatus, $changedItem = null, $error = null) {

        $webSilo = $subscriptionGroup->modifiedByWebUser->customer->webSilo;
        $client = new Klaviyo($webSilo->klaviyo_api_key, $webSilo->klaviyo_company_id);

        $itemArray = [];
        foreach($subscriptionGroup->subscriptionItems as $subscriptionItem) {
            $part = $subscriptionItem->part;
            $webFamily = $part->webFamily;
            $webPart = $part->webPart;
            $itemArray[] = [
                'ProductID' => $part->part_no,
                'ProductName' => $part->part_desc,
                'Quantity' => $subscriptionItem->quantity,
                'ProductURL' => route('family.slug', [Arr::get($webFamily, 'slug', ''), Arr::get($webPart, 'id', '')]),
                'SmallImageURL' => WebAsset::urlHelper(['key' => Arr::get($part, 'part_no', ''), 'prefix' => 'pn', 'width' => 150, 'height' => 150]),
                'ImageURL' => WebAsset::urlHelper(['key' => Arr::get($part, 'part_no', ''), 'prefix' => 'pn']),
                'ItemPrice' => b2b()->formatPrice($cartStatus['items'][$subscriptionItem->id]['discountedPrice']),
                'RowTotal' => b2b()->formatPrice($cartStatus['items'][$subscriptionItem->id]['discountedPrice'])
            ];
        }


        if ($changedItem != null) {
            $event = new KlaviyoEvent([
                'event' => $eventName,
                'customer_properties' => [
                    '$id' => $subscriptionGroup->modifiedByWebUser != null ? $subscriptionGroup->modifiedByWebUser->id : '',
                    '$email' => $subscriptionGroup->modifiedByWebUser != null ? $subscriptionGroup->modifiedByWebUser->email : ''
                ],
                'properties' => [
                    'error_message' => $error != null ? $error : '',

                    'group_name' => $subscriptionGroup->label,
                    'next_order_date' => $subscriptionGroup->next_order_date,
                    'cadence' => $subscriptionGroup->subscriptionPeriod->period_name,
                    'delayed_counter' => $subscriptionGroup->delayed_counter,
                    'group_type' => $subscriptionGroup->subscriptiongroup_type,
                    
                    'billto_customer_number' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->cust_no : '',
                    'billto_customer_name' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->cust_name : '',
                    'billto_addr_1' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_1 : '',
                    'billto_addr_2' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_2 : '',
                    'billto_addr_3' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_3 : '',
                    'billto_addr_4' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_4 : '',
                    'billto_addr_5' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_5 : '',
                    'billto_city' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_city : '',
                    'billto_state' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_state : '',
                    'billto_zip' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_zip_postal : '',
                    'billto_country' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_country : '',

                    'shipto_addr_number' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_no : '',
                    'shipto_customer_name' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->cust_name : '',
                    'shipto_addr_1' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_1 : '',
                    'shipto_addr_2' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_2 : '',
                    'shipto_addr_3' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_3 : '',
                    'shipto_addr_4' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_4 : '',
                    'shipto_addr_5' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_5 : '',
                    'shipto_city' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->city : '',
                    'shipto_state' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->state : '',
                    'shipto_zip' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->postal_cd : '',
                    'shipto_country' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->country : '',

                    'items' => $itemArray,
                    'changedItem' => $changedItem,
                    'discountTotal' => number_format($cartStatus['baseTotal'] - $cartStatus['discountedTotal'], 2),
                    'taxAmount' => $cartStatus['taxAmount'],
                    'orderTotal' => $cartStatus['orderTotal'],
                ],
            ]);
        } else {
            $event = new KlaviyoEvent([
                'event' => $eventName,
                'customer_properties' => [
                    '$id' => $subscriptionGroup->modifiedByWebUser != null ? $subscriptionGroup->modifiedByWebUser->id : '',
                    '$email' => $subscriptionGroup->modifiedByWebUser != null ? $subscriptionGroup->modifiedByWebUser->email : ''
                ],
                'properties' => [
                    'error_message' => $error != null ? $error : '',

                    'group_name' => $subscriptionGroup->label,
                    'next_order_date' => $subscriptionGroup->next_order_date,
                    'cadence' => $subscriptionGroup->subscriptionPeriod->period_name,
                    'delayed_counter' => $subscriptionGroup->delayed_counter,
                    'group_type' => $subscriptionGroup->subscriptiongroup_type,


                    'billto_customer_number' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->cust_no : '',
                    'billto_customer_name' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->cust_name : '',
                    'billto_addr_1' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_1 : '',
                    'billto_addr_2' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_2 : '',
                    'billto_addr_3' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_3 : '',
                    'billto_addr_4' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_4 : '',
                    'billto_addr_5' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_addr_5 : '',
                    'billto_city' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_city : '',
                    'billto_state' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_state : '',
                    'billto_zip' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_zip_postal : '',
                    'billto_country' => $subscriptionGroup->billToCustomer != null ? $subscriptionGroup->billToCustomer->bill_country : '',

                    'shipto_addr_number' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_no : '',
                    'shipto_customer_name' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->cust_name : '',
                    'shipto_addr_1' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_1 : '',
                    'shipto_addr_2' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_2 : '',
                    'shipto_addr_3' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_3 : '',
                    'shipto_addr_4' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_4 : '',
                    'shipto_addr_5' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->addr_5 : '',
                    'shipto_city' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->city : '',
                    'shipto_state' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->state : '',
                    'shipto_zip' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->postal_cd : '',
                    'shipto_country' => $subscriptionGroup->customerShippingAddress != null ? $subscriptionGroup->customerShippingAddress->country : '',

                    'items' => $itemArray,
                    'discountTotal' => number_format($cartStatus['baseTotal'] - $cartStatus['discountedTotal'], 2),
                    'taxAmount' => $cartStatus['taxAmount'],
                    'orderTotal' => $cartStatus['orderTotal'],
                ],
            ]);
        }

        $client->publicAPI->track($event);
    }

    public function orders() {
        return $this->belongsToMany(Order::class, 'SalesOrder_SubscriptionGroup', 'subscriptiongroup_id', 'salesorder_id');
    }

    public function getOrderCounterAttribute() {
        return $this->orders()->count();
    }

    public function scopeSubscriptiongroupType($query, $type) {
        $query->where('subscriptiongroup_type', $type);
    }

    public function calculateAndUpdateSubscriptionGroupType() {
        $type = 'default';
        foreach ($this->subscriptionItems as $item) {
            if (in_array(\Arr::get($item, 'part.item_type', ''), config('hilco.custom_item_types', ['D15']))) {
                $type = 'custom';
            }
        }
        $this->subscriptiongroup_type = $type;
        $this->save();
    }

    public function submissionRule() {
        return $this->hasOne(SubscriptionSubmissionRules::class, 'subscriptiongroup_type', 'subscriptiongroup_type');
    }

    public function notificationRules() {
        return $this->hasMany(SubscriptionNotificationRules::class, 'subscriptiongroup_type', 'subscriptiongroup_type');
    }

    public function getNextSubmissionDateAttribute() {
        $submissionRule = $this->submissionRule;
        if (is_null($submissionRule)) return false;

        if ($submissionRule->count_from == 'next_order_date') $sourceDate = Carbon::create($this->next_order_date);
        else $sourceDate = false;

        if ($sourceDate === false) return false;

        $counter = $submissionRule->count_days;
        while ($counter > 0) {
            if ($submissionRule->day_type === 'calendar') {
                $sourceDate = $sourceDate->subDay();
            } else if ($submissionRule->day_type === 'business') {
                $sourceDate = $sourceDate->subDay();
                while ($sourceDate->isWeekend()) {
                    $sourceDate = $sourceDate->subDay();
                }
            } else {
                return false;
            }

            $counter--;
        }

        return $sourceDate->toDateString();
    }

    public function getNextNotificationDatesAttribute() {
        $notificationRules = $this->notificationRules;
        if (is_null($notificationRules)) return [];

        $return = [];

        foreach ($notificationRules as $notificationRule) {

            if ($notificationRule->count_from === 'next_order_date') $sourceDate = Carbon::create($this->next_order_date);
            else if ($notificationRule->count_from === 'submission_date') $sourceDate = Carbon::create($this->next_submission_date);
            else $sourceDate = false;

            ///WHAT
            if ($sourceDate === false) {
                $return[$notificationRule->notification_type] = false;
                continue;
            }

            $counter = $notificationRule->count_days;
            while ($counter > 0) {
                if ($notificationRule->day_type === 'calendar') {
                    $sourceDate = $sourceDate->subDay();
                } else if ($notificationRule->day_type === 'business') {
                    $sourceDate = $sourceDate->subDay();
                    while ($sourceDate->isWeekend()) {
                        $sourceDate = $sourceDate->subDay();
                    }
                } else {
                    return false;
                }

                $counter--;
            }

            $return[$notificationRule->notification_type] = $sourceDate->toDateString();
        }

        return $return;
    }

//    public function scopeHasCustom($query) {
//        $query->whereHas('subscriptionItems', function ($query) {
//            $query->whereHas('part', function ($query) {
//                $query->whereIn('item_type', config('hilco.custom_item_types', ['D15']));
//            });
//        });
//    }
//
//    public function scopeHasNoCustom($query) {
//        $query->whereHas('subscriptionItems', function ($query) {
//            $query->whereHas('part', function ($query) {
//                $query->whereNotIn('item_type', config('hilco.custom_item_types', ['D15']));
//            });
//        });
//    }
//
//    public function getHasCustomAttribute() {
//        $hasCustom = false;
//        foreach ($this->subscriptionItems as $item) {
//            if (in_array(Arr::get($item, 'part.item_type'), config('hilco.custom_item_types', ['D15'])));
//        }
//    }
}