<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\BaseModel;
use Illuminate\Support\Arr;

class StoreOrder extends BaseModel
{
    use HasFactory;

    protected $table = 'store_order';
    public $timestamps = false;

    public function user(){
        return $this->hasOne(User::class, 'id', 'user_id');
    }
    public function client(){
        return $this->hasOne(User::class, 'id', 'user_id');
    }

    public function associatedOrders($parentOrderId){
        return StoreOrder::where('parent_order_id', $parentOrderId)->get();
    }

    public function allAssociatedOrders(){
        $orders = StoreOrder::where('parent_order_id', $this->id)->get();
        $orders->prepend($this);
        return $orders;
    }


    public function paymentMethod(){
        return $this->hasOne(PaymentMethod::class, 'id', 'payment_method_id');
    }
    public function financialTransactions(){
        return $this->hasMany(FinancialTransaction::class, 'order_id', 'id');
    }
    public function finalFinancialTransaction(){
        return FinancialTransaction::where('order_id', $this->id)->orderBy('created_at', 'DESC')->first();
    }

    public function orderNumber() {
        if ($this->iid) return $this->iid;
        return getFirstSectionUID($this->uid);
    }

    public function tests(){
        $detail = json_decode($this->detail_json);
        $selectedOptions = json_decode(@$detail->selected_options);
        if(!$selectedOptions) return [];
        return (array) @$selectedOptions->tests;
    }

    public function partnerTests(){
        $detail = json_decode($this->detail_json);
        $selectedOptions = json_decode(@$detail->selected_options);
        if(!$selectedOptions) return [];
        return (array) @$selectedOptions->tests;
    }

    public function testsRequested(){
        $tests = (array) $this->tests();
        $data = [];
        foreach($tests as $key=>$value){
            if($value){
                array_push($data, $key);
            }
        }
        return $data;
    }
    public function partnerTestsRequested(){
        $tests = (array) $this->partnerTests();
        $data = [];
        foreach($tests as $key=>$value){
            if($value){
                array_push($data, $key);
            }
        }
        return $data;
    }


    public function testsRequestedInHumanReadable(){
        $data = [];
        $tests = $this->testsRequested();
        $allTests = getAllTests();
        foreach($tests as $test){
            $testName = @$allTests[$test]['label'];
            $testPrice = displayAmount('$', config('app.'.$test));
            $string = $testName . ' - '.$testPrice;
            array_push($data, $string);
        }
        return $data;
    }

    public function partnerTestsRequestedInHumanReadable(){
        $data = [];
        $tests = $this->partnerTestsRequested();
        $discount = $this->getPartnerTestDiscount();
        $allTests = getAllTests();
        foreach($tests as $test){
            $testName = $allTests[$test]['label'];
            $testPrice = floatval(config('app.'.$test));
            $testCost = $testPrice - $discount;
            $string = $testName . ' - '. displayAmount('$', $testCost);
            array_push($data, $string);
        }
        return $data;
    }

    public function getPartnerTestDiscount(){
        $detail = json_decode($this->detail_json);
        $selectedOptions = json_decode(@$detail->selected_options);
        if(!$selectedOptions) return 0;
        if(!@$selectedOptions->partner_test_discount_amount) return 0;
        return floatval(@$selectedOptions->partner_test_discount_amount);
    }

    public function getPartnerEmail(){
        $detail = json_decode($this->detail_json);
        $selectedOptions = json_decode(@$detail->selected_options);
        if(!$selectedOptions) return null;
        if(!@$selectedOptions->partner_email) return null;
        return @$selectedOptions->partner_email;
    }


    public function total(){
        $total = $this->order_total;
        $orders = $this->associatedOrders($this->id);
        foreach($orders as $order){
            $total = $total +  $order->order_total;
        }
        return $total;
    }

    public function lab(){
        $detail = json_decode($this->detail_json);
        $selectedOptions = json_decode(@$detail->selected_options);
        $labID = @$selectedOptions->tests_lab_id;
        if(!$labID) return null;
        return Lab::where('id', $labID)->first();
    }

    public function createdByUser(){
        return $this->hasOne(User::class, 'id', 'created_by_user_id');
    }

    public function detailJson($toArray = false)
    {
        if($toArray){
            return json_decode($this->detail_json ?? '{}', true);
        }
        return json_decode($this->detail_json ?? '{}');
    }

    public function getDetailJsonValue($field)
    {
        $parsed = $this->detailJson(true);
        if (isset($parsed[$field])) {
            return $parsed[$field];
        }
        return null;
    }

    public function selectedOptions(){
        $orderDetailJson = $this->detailJson();
        return json_decode(@$orderDetailJson->selected_options ?? '{}', true);
    }

    public function getOrderTestsSummary(){
        $orderSelectedOptions = $this->selectedOptions();
        $tests = @$orderSelectedOptions['tests'] ?? [];
        $data = [];
        foreach($tests as $k=>$v){
            if($v){
                $data[$k] = $v;
            }
        }
        return $data;
    }

    public function getOrderAllTestsRequested(){
        $summary = [];
        $allTests = [];
        $hasPartner = false;
        $partnerDiscount = 0;
        $orderTotal = 0;
        $partnerTotal = 0;
        $orders = $this->allAssociatedOrders();
        foreach($orders as $order){
            $orderSelectedOptions = $this->selectedOptions();
            $hasPartner = @$orderSelectedOptions['partner'] ? true:false;
            $partnerDiscount = floatval(@$orderSelectedOptions['partner_test_discount_amount']);            
            $allTests = array_merge($allTests, (array) $order->getOrderTestsSummary());
            $partnerTotal = $partnerTotal + floatval(@$orderSelectedOptions['partner_test_total']);
            $orderTotal = $orderTotal + floatval($order->order_total);
        }
        $summary['all_tests'] = $allTests;
        $summary['client_total'] = $orderTotal - $partnerTotal;
        $summary['partner_total'] = $partnerTotal;
        $summary['sub_total'] = $orderTotal + $partnerDiscount;
        $summary['final_total'] = $orderTotal;
        $summary['has_partner'] = $hasPartner;
        $summary['partner_total_discount'] = $partnerDiscount;

        return $summary;
    }

    public function getRequisitionFormAccessToken(){
        return $this->getDetailJsonValue('requisition_form_access_token');
    }

    public function requisitionFormTokenAccessUrl(){
        $accessToken = $this->getRequisitionFormAccessToken();
        $url = config('app.orderAppUrl').'/requisition-form/download/'.$accessToken;
        return $url;
    }

}
