<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\TrackingUpdate;

class Shipment extends Model
{
    protected $fillable = [
        'tracking_number',
        'sender_name',
        'sender_contact',
        'sender_email',
        'sender_address',
        'status',
        'dispatch_location',
        'show_map',
        'receiver_email',
        'receiver_name',
        'receiver_contact',
        'receiver_address',
        'dispatch_date',
        'delivery_date',
        'pdesc',
        'destination',
        'current_location',
        'carrier',
        'carrier_ref',
        'ship_mode',
        'weight',
        'quantity',
        'payment_mode',
        'image',
        'travel_progress',
        'delivery_time',
        'total_f'
    ];

    protected $dates = [
        'dispatch_date',
        'delivery_date',
        'date',
        'dateupdated'
    ];
    
     public function trackingUpdates()
    {
        return $this->hasMany(TrackingUpdate::class);
    }

    public function getLocationHistory()
{
    $history = [];

    // Add initial location (dispatch location)
    if ($this->dispatch_location) {
        // Get the first tracking update with valid coordinates to possibly use for origin
        $firstUpdate = $this->trackingUpdates()
            ->whereNotNull('latitude')
            ->whereNotNull('longitude')
            ->orderBy('created_at', 'asc')
            ->first();
            
        // Use coordinates from first update if available, otherwise zeros
        $lat = $firstUpdate ? (float)$firstUpdate->latitude : 0;
        $lng = $firstUpdate ? (float)$firstUpdate->longitude : 0;
        
        $history[] = [
            'name' => $this->dispatch_location,
            'lat' => $lat,
            'lng' => $lng,
            'date' => $this->dispatch_date,
            'status' => 'Dispatched'
        ];
    }

    // Add tracking updates
    foreach ($this->trackingUpdates as $update) {
        // Only add updates with valid coordinates
        if ($update->latitude && $update->longitude) {
            $lat = (float)$update->latitude;
            $lng = (float)$update->longitude;
            
            // Skip obviously invalid coordinates (both exactly zero)
            if ($lat == 0 && $lng == 0) {
                continue;
            }
            
            $history[] = [
                'name' => $update->location,
                'lat' => $lat,
                'lng' => $lng,
                'date' => $update->created_at->format('Y-m-d H:i:s'),
                'status' => $update->status,
                'description' => $update->description
            ];
        }
    }

    // Add current location if different from last update and not destination
    if ($this->current_location && $this->current_location !== $this->destination) {
        // Find the update for current location
        $currentLocationUpdate = $this->trackingUpdates()
            ->where('location', $this->current_location)
            ->whereNotNull('latitude')
            ->whereNotNull('longitude')
            ->orderBy('created_at', 'desc')
            ->first();
            
        // Only add if not already in history
        $isAlreadyInHistory = false;
        foreach ($history as $item) {
            if ($item['name'] === $this->current_location) {
                $isAlreadyInHistory = true;
                break;
            }
        }
        
        if (!$isAlreadyInHistory) {
            // Use coordinates from the update if available
            $lat = $currentLocationUpdate ? (float)$currentLocationUpdate->latitude : 0;
            $lng = $currentLocationUpdate ? (float)$currentLocationUpdate->longitude : 0;
            
            // If coordinates are valid
            if (!($lat == 0 && $lng == 0) || !$currentLocationUpdate) {
                $history[] = [
                    'name' => $this->current_location,
                    'lat' => $lat,
                    'lng' => $lng,
                    'date' => $currentLocationUpdate ? $currentLocationUpdate->created_at->format('Y-m-d H:i:s') : now()->format('Y-m-d H:i:s'),
                    'status' => $this->status
                ];
            }
        }
    }

    // Add destination
    if ($this->destination) {
        // Try to find destination coordinates in updates
        $destinationUpdate = $this->trackingUpdates()
            ->where('location', $this->destination)
            ->whereNotNull('latitude')
            ->whereNotNull('longitude')
            ->orderBy('created_at', 'desc')
            ->first();
            
        // Get the last tracking update with valid coordinates
        $lastUpdate = $this->trackingUpdates()
            ->whereNotNull('latitude')
            ->whereNotNull('longitude')
            ->orderBy('created_at', 'desc')
            ->first();
            
        // If destination is already delivered, use last update's coordinates
        // Otherwise try destination update or use a position further from last known point
        $lat = 0;
        $lng = 0;
        
        if ($this->status === 'delivered' && $lastUpdate) {
            $lat = (float)$lastUpdate->latitude;
            $lng = (float)$lastUpdate->longitude;
        } elseif ($destinationUpdate) {
            $lat = (float)$destinationUpdate->latitude;
            $lng = (float)$destinationUpdate->longitude;
        } elseif ($lastUpdate) {
            // Calculate a position in the same direction but further
            $lat = (float)$lastUpdate->latitude;
            $lng = (float)$lastUpdate->longitude;
            
            // Get the second to last update to determine direction
            $secondLastUpdate = $this->trackingUpdates()
                ->whereNotNull('latitude')
                ->whereNotNull('longitude')
                ->where('id', '!=', $lastUpdate->id)
                ->orderBy('created_at', 'desc')
                ->first();
                
            if ($secondLastUpdate) {
                $prevLat = (float)$secondLastUpdate->latitude;
                $prevLng = (float)$secondLastUpdate->longitude;
                
                // Calculate direction vector and extend it
                $vectorLat = $lat - $prevLat;
                $vectorLng = $lng - $prevLng;
                
                // Extend by 20% in the same direction
                $lat = $lat + ($vectorLat * 0.2);
                $lng = $lng + ($vectorLng * 0.2);
            }
        }
        
        // Only add destination if we have some history or valid coordinates
        if (count($history) > 0 || ($lat != 0 && $lng != 0)) {
            $history[] = [
                'name' => $this->destination,
                'lat' => $lat,
                'lng' => $lng,
                'date' => $this->delivery_date,
                'status' => $this->status === 'delivered' ? 'Delivered' : 'Destination'
            ];
        }
    }

    return $history;
}

}
