<?php

class Tracking_EasyPost {

    /**
     *
     * @param string $code
     * @return \TrackingInfo
     * @throws TrackingException
     */
    public static function track(string $code, string $carrier = ""): TrackingInfo {
        $barcode = new TrackingBarcode($code);

        \EasyPost\EasyPost::setApiKey(env("easypost_key"));

        try {
            if (empty($carrier)) {
                $tracker = \EasyPost\Tracker::create(array(
                            "tracking_code" => $code
                ));
            } else {
                $trackinginfo["carrier"] = $carrier;
                $tracker = \EasyPost\Tracker::create(array(
                            "tracking_code" => $code,
                            "carrier" => $carrier
                ));
            }
        } catch (Exception $ex) {
            if (env("debugmode", false)) {
                echo $ex->getMessage();
                echo $ex->getTraceAsString();
            }
            throw new TrackingException("There was a server problem. This code cannot be tracked right now.");
        }

        $info = new TrackingInfo();

        $info->setCode($tracker->tracking_code);
        $info->setCarrier(strtolower($tracker->carrier));
        $info->setCarrierAttributionText(CarrierAssets::getAttribution(Carriers::getCarrierCode($info->getCarrier())));
        $info->setCarrierLogo(CarrierAssets::getLogo(Carriers::getCarrierCode($info->getCarrier())));

        if (!empty($tracker->tracking_details) && count($tracker->tracking_details) > 0) {

            $events_sorted = $tracker->tracking_details;

            // start https://stackoverflow.com/a/2910637
            function date_compare($a, $b) {
                $t1 = strtotime($a->datetime);
                $t2 = strtotime($b->datetime);
                return $t2 - $t1;
            }
            usort($events_sorted, 'date_compare');
            // end https://stackoverflow.com/a/2910637

            foreach ($events_sorted as $history) {
                $location = new Location();
                $location->city = $history->tracking_location["city"];
                $location->state = $history->tracking_location["state"];
                $location->zip = $history->tracking_location["zip"];
                $location->country = $history->tracking_location["country"];
                $info->appendHistoryEntry(new TrackingEntry(TrackingStatus::stringToStatus($history->status), $history->message, $history->datetime, $location));
            }

            $current_status = new TrackingEntry(
                    TrackingStatus::stringToStatus(
                            $events_sorted[0]->status),
                    $events_sorted[0]->message,
                    $events_sorted[0]->datetime
            );
            if (!empty($events_sorted[0]->tracking_location)) {
                $current_location = new Location();
                $current_location->city = $events_sorted[0]->tracking_location->city;
                $current_location->state = $events_sorted[0]->tracking_location->state;
                $current_location->zip = $events_sorted[0]->tracking_location->zip;
                $current_location->country = $events_sorted[0]->tracking_location->country;
                $current_status->setLocation($current_location);
            }
            $info->setCurrentStatus($current_status);
        }

        if (!empty($tracker->carrier_detail->origin_tracking_location)) {
            $from = new Location();
            $from->city = $tracker->carrier_detail->origin_tracking_location->city ?? "";
            $from->state = $tracker->carrier_detail->origin_tracking_location->state ?? "";
            $from->zip = $tracker->carrier_detail->origin_tracking_location->zip ?? "";
            $from->country = $tracker->carrier_detail->origin_tracking_location->country ?? "";

            $info->setFrom($from);
        }

        if (!empty($tracker->carrier_detail->destination_tracking_location)) {
            $to = new Location();
            $to->city = $tracker->carrier_detail->destination_tracking_location->city ?? "";
            $to->state = $tracker->carrier_detail->destination_tracking_location->state ?? "";
            $to->zip = $tracker->carrier_detail->destination_tracking_location->zip ?? "";
            $to->country = $tracker->carrier_detail->destination_tracking_location->country ?? "";

            $info->setTo($to);
        }

        return $info;
    }

}
