<?php

namespace App\Repositories\Member;

use App\ThirdParty\Biteship\Biteship;

use App\Models\Cart;
use App\Models\Location;
use App\Models\Address;
use App\Models\Transaction;

use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class ShippingRepository
{

    var $biteship;

    public function __construct(Biteship $biteship) {
        $this->biteship = $biteship;
    }

    public function calcTotal($params){
        $user = auth()->user();
        $location = Location::findOrFail(@$params["location_id"]);
        $items = Cart::where("user_id", $user->id)
            ->where("location_id", $location->id)
            ->get();
        $total_amount = 0;
        foreach($items as $detail){
                $convertion = 1;
                if ($detail->item->display_unit and $detail->item->display_unit != $detail->item->unit){
                    $convertions =  DB::select("select to_qty / from_qty as conv from item_convertions where from_unit = ? and to_unit =  ?",
[$detail->item->display_unit, $detail->item->unit]);
                    $convertion = max((float) @$convertions[0]->conv,1);
                }
                $d_price = @$detail->itemReference->discount->price ?? 0;
                $s_price = @$detail->itemReference->price->price ?? 0;
                $price = ( $s_price ? $s_price : $detail->item->net_price) * $convertion;
                $price = ( $d_price ? $d_price : $price) * $convertion;
                $total = $detail->qty * $price;
                $total_amount = $total_amount + $total;
        }
        return $total_amount;

    }
    public function getList($params)
    {
        $biteship = $this->biteship;
        $location = Location::findOrFail(@$params["location_id"]);
        $address = Address::findOrFail(@$params["address_id"]);

        if (!$location->postal_code){
            throw ValidationException::withMessages([
                "location_id" => "Data gudang tidak memiliki informasi kode pos"
            ]);
        }

        if (!$location->latitude || !$location->longitude){
            throw ValidationException::withMessages([
                "location_id" => "Data gudang tidak memiliki informasi lat long"
            ]);
        }

        $hasLatLong = $address->latitude != null && $address->longitude != null;
        $items = collect(@$params["items"] ?? []);


        $user = auth()->user();

        $items = collect(@$data["items"] ?? []);

        $items = Cart::where("user_id", $user->id)
            ->where("location_id", $location->id)
            ->when(count($items) > 0, function($query) use ($items){
                $query->whereIn("item_reference_id", $items->pluck("item_reference_id"));
            })
            ->get();

        $items = $items->map(function($cart){
            if (((float) @$cart->item->weight) <= 0){
                throw ValidationException::withMessages([
                    "location_id" => "Berat ada yang kosong"
                ]);
            }
            return [
                "weight" => max(@$cart->item->weight,0.001),
                "quantity" => @$cart->qty,
                "value" => @$cart->item->net_price,
                "description" => @$cart->itemVariant->description ?? @$cart->item->name,
                "name" => @$cart->item->category->name ?? "GOODS"
            ];
        });

        if ($hasLatLong){
            $list = $biteship->rateByLatLong([
                "origin_latitude" => $location->latitude,
                "origin_longitude" => $location->longitude,
                "destination_latitude" => $address->latitude,
                "destination_longitude" => $address->longitude,
                "items" => $items
            ]);
      
        }else{
            $list = $biteship->rateByPostal([
                "origin_postal_code" => $location->postal_code,
                "destination_postal_code" => $address->postal_code,
                "items" => $items
            ]);
        }
        
        return $list;
    }


    public function order(Transaction $transaction)
    {
        $biteship = $this->biteship;
        $location = $transaction->location;
        $address = $transaction->address;

        if (!$location->postal_code){
            throw ValidationException::withMessages([
                "location_id" => "Data gudang tidak memiliki informasi kode pos"
            ]);
        }

        if (!$location->latitude || !$location->longitude){
            throw ValidationException::withMessages([
                "location_id" => "Data gudang tidak memiliki informasi lat long"
            ]);
        }

        $hasLatLong = $address->latitude != null && $address->longitude != null;
        $user = auth()->user();
        $items = $transaction->details;
        $items = $items->map(function($cart){
            if (((float) @$cart->item->weight) == 0){
                throw ValidationException::withMessages([
                    "items" => "Berat item wajib diisi!"
                ]);
            }

            return [
                "weight" => max(@$cart->item->weight,0.001),
                "quantity" => @$cart->qty,
                "value" => @$cart->item->net_price,
                "description" => @$cart->itemVariant->description ?? @$cart->item->name,
                "name" => @$cart->item->category->name ?? "GOODS"
            ];
        });
        $subtotal = $items->reduce(function($acc, $cart){
            return $acc + ( @$cart->qty * @$cart->item->net_price);
        },0);

        if ($hasLatLong){
            return $biteship->orderByLatLong(
                [
                    "origin_contact_name" => $location->display_name,
                    "origin_contact_phone" => $location->phone,
                    "origin_address" => $location->address,
                    "origin_latitude" => $location->latitude,
                    "origin_longitude" => $location->longitude,

                    "destination_contact_name" => $address->name,
                    "destination_contact_phone" => $address->phone,
                    "destination_latitude" => $address->latitude,
                    "destination_longitude" => $address->longitude,
                    "destination_address"  => $address->address,

                    "reference_id" => $transaction->number,

                    "courier_insurance" => $subtotal,
                    "courier_company" => $transaction->courier_company,
                    "courier_type" => $transaction->courier_type,
                    "items" => $items
                ]
            );
        }else{
            $destination_address = $address->address;
            if (@$address->subdistrict->name)
                $destination_address .= "," .@$address->subdistrict->name;
            if (@$address->district->name)
                $destination_address .= "," .@$address->district->name;
            if (@$address->city->name)
                $destination_address .= "," .@$address->city->name;
            if (@$address->province->name)
                $destination_address .= "," .@$address->province->name;
            return $biteship->orderByPostal(
                [
                    "origin_contact_name" => $location->display_name,
                    "origin_contact_phone" => $location->phone,
                    "origin_address" => $location->address,
                    "origin_postal_code" => $location->postal_code,
                    "origin_latitude" => $location->latitude,
                    "origin_longitude" => $location->longitude,

                    "destination_contact_name" => $address->name,
                    "destination_contact_phone" => $address->phone,
                    "destination_address" => $destination_address,
                    "destination_postal_code" => $address->postal_code,

                    "reference_id" => $transaction->number,
                    "courier_insurance" => $subtotal,

                    "courier_company" => $transaction->courier_company,
                    "courier_type" => $transaction->courier_type,
                    "items" => $items
                ]
            );
        }
    }

    public function tracking(Transaction $transaction, $waybill = true){
        $biteship = $this->biteship;
        $shipping = $transaction->shipping;

        if (!@$shipping){

            throw ValidationException::withMessages([
                "shipping" => "Belum ada process pengiriman!"
            ]);

            if ($waybill){

                $data = (array) $biteship->trackingByWaybill([
                    "id" => $shipping->tracking_id,
                    "waybill_id" => $shipping->waybill_id,
                    "courier" => $shipping->courier,
                ]);
            }else{

                $data = (array) $biteship->trackingById([
                    "id" => $shipping->tracking_id,
                    "waybill_id" => $shipping->waybill_id,
                    "courier" => $shipping->courier,
                ]);
            }

            $shipping->tracks()->delete();
            foreach($data["history"] as $history){
                $history = (array) $history;
                $shipping->tracks()->create([
                    "status" => $history["status"],
                    "note" => $history["note"],
                    "created_at" => @$history["updated_at"]
                ]);
            }
            $shipping->fill([
                "status" => $data["status"]
            ]);
            $shipping->update();

        }
    }
}
