<?php

namespace App\Notifications;

use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

/**
 * Notification sent to customer when their order is shipped.
 */
class OrderShipped extends Notification implements ShouldQueue
{
    use Queueable;

    public function __construct(
        public Order $order
    ) {}

    public function via(object $notifiable): array
    {
        // Database first to ensure in-app notification is saved even if email fails
        return ['database', 'mail'];
    }

    public function toMail(object $notifiable): MailMessage
    {
        $message = (new MailMessage)
            ->subject('Tu Pedido Ha Sido Enviado - #' . $this->order->order_number)
            ->greeting('¡Hola ' . $notifiable->name . '!')
            ->line('¡Buenas noticias! Tu pedido ya está en camino.')
            ->line('')
            ->line('**Detalles del Envío:**')
            ->line('• Número de Pedido: ' . $this->order->order_number)
            ->line('• Fecha de Envío: ' . $this->order->shipped_at->format('d/m/Y H:i'));

        if ($this->order->tracking_number) {
            $message->line('• Número de Rastreo: ' . $this->order->tracking_number);
        }

        if ($this->order->tracking_url) {
            $message->action('Rastrear Mi Pedido', $this->order->tracking_url);
        } else {
            $message->action('Ver Detalles del Pedido', $this->getOrderUrl($notifiable));
        }

        $message->line('')
            ->line('**Dirección de Entrega:**')
            ->line($this->formatShippingAddress())
            ->line('')
            ->line('Si tienes alguna pregunta, no dudes en contactarnos.')
            ->salutation('¡Gracias por tu compra!');

        return $message;
    }

    public function toArray(object $notifiable): array
    {
        return [
            'type' => 'order_shipped',
            'order_id' => $this->order->id,
            'order_number' => $this->order->order_number,
            'tracking_number' => $this->order->tracking_number,
            'tracking_url' => $this->order->tracking_url,
            'shipped_at' => $this->order->shipped_at?->toISOString(),
            'message' => "Tu pedido #{$this->order->order_number} ha sido enviado",
            'title' => 'Pedido Enviado',
            'url' => $this->order->tracking_url ?? $this->getOrderUrl($notifiable),
        ];
    }

    protected function formatShippingAddress(): string
    {
        $address = $this->order->shipping_address;
        if (!is_array($address)) {
            return 'Dirección no disponible';
        }

        $lines = [];
        if (!empty($address['first_name']) || !empty($address['last_name'])) {
            $lines[] = trim(($address['first_name'] ?? '') . ' ' . ($address['last_name'] ?? ''));
        }
        if (!empty($address['address_line1'])) {
            $lines[] = $address['address_line1'];
        }
        if (!empty($address['address_line2'])) {
            $lines[] = $address['address_line2'];
        }
        if (!empty($address['city'])) {
            $cityLine = $address['city'];
            if (!empty($address['state'])) {
                $cityLine .= ', ' . $address['state'];
            }
            if (!empty($address['postal_code'])) {
                $cityLine .= ' ' . $address['postal_code'];
            }
            $lines[] = $cityLine;
        }

        return implode("\n", $lines);
    }

    protected function getOrderUrl(object $notifiable): string
    {
        $prefix = match($notifiable->role) {
            'admin' => 'admin',
            'coach' => 'coach',
            default => 'client',
        };

        return route("{$prefix}.store.orders.show", $this->order->id);
    }

    public function databaseType(object $notifiable): string
    {
        return 'order_shipped';
    }
}
