<?php

namespace App\Services;

use App\Models\Setting;
use App\Models\Ticket;
use App\Models\TicketDepartment;
use App\Models\TicketReply;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

/**
 * Sends ticket-related push notifications to a department's Pushover recipient.
 *
 * The department.pushover_user_key can be:
 *   - A single user key (starts with "u...") — notifies one admin
 *   - A group key (starts with "g...") — notifies all members of a Pushover delivery group,
 *     which is Pushover's native way to fan out to multiple devices/users.
 *
 * Pushover has no thread/channel concept — every event is an independent push notification.
 */
class TicketPushoverService
{
    private const API_URL = 'https://api.pushover.net/1/messages.json';

    public function isEnabled(TicketDepartment $department): bool
    {
        return $department->pushover_enabled
            && !empty($department->pushover_user_key)
            && !empty(Setting::get('pushover_app_token'));
    }

    public function sendTicketOpened(Ticket $ticket): void
    {
        $department = $ticket->department;
        if (!$this->isEnabled($department)) {
            return;
        }

        $client = $ticket->client;
        $clientName = $client ? trim($client->first_name . ' ' . $client->last_name) : 'Guest';
        $firstMessage = $ticket->replies()->oldest()->first()?->message ?? '';

        $title = "🎫 New Ticket #{$ticket->id}";
        $message = "Subject: " . Str::limit($ticket->title ?? '-', 100) . "\n"
            . "Priority: " . ucfirst($ticket->priority ?? 'normal') . "\n"
            . "Client: {$clientName}\n"
            . "Dept: " . ($department->name ?? '-') . "\n\n"
            . Str::limit($firstMessage, 300);

        $this->send(
            $department->pushover_user_key,
            $title,
            $message,
            priority: $this->mapPriority($ticket->priority),
            url: $this->ticketUrl($ticket),
        );
    }

    public function sendReply(Ticket $ticket, TicketReply $reply): void
    {
        $department = $ticket->department;
        if (!$this->isEnabled($department) || $reply->is_internal) {
            return;
        }

        $authorName = $reply->isFromAdmin()
            ? ($reply->admin?->name ?? 'Admin')
            : trim(($reply->client?->first_name ?? '') . ' ' . ($reply->client?->last_name ?? ''));

        $label = $reply->isFromAdmin() ? '👤 Staff Reply' : '💬 Client Reply';

        $title = "{$label} on #{$ticket->id}";
        $message = "By: {$authorName}\n\n" . Str::limit($reply->message ?? '', 400);

        $this->send(
            $department->pushover_user_key,
            $title,
            $message,
            url: $this->ticketUrl($ticket),
        );
    }

    public function sendTicketClosed(Ticket $ticket): void
    {
        $department = $ticket->department;
        if (!$this->isEnabled($department)) {
            return;
        }

        $this->send(
            $department->pushover_user_key,
            "✅ Ticket #{$ticket->id} Closed",
            Str::limit($ticket->title ?? '-', 200),
            url: $this->ticketUrl($ticket),
        );
    }

    public function sendEscalationNotice(Ticket $ticket, string $ruleName, array $changes): void
    {
        $department = $ticket->department;
        if (!$this->isEnabled($department)) {
            return;
        }

        $parts = ["Rule: {$ruleName}"];
        if (isset($changes['department_id'])) $parts[] = '• Department changed';
        if (isset($changes['priority'])) $parts[] = "• Priority: {$changes['priority']['from']} → {$changes['priority']['to']}";
        if (isset($changes['flagged'])) $parts[] = '• Flagged';

        $this->send(
            $department->pushover_user_key,
            "🚨 Ticket #{$ticket->id} Escalated",
            implode("\n", $parts),
            priority: 1, // Pushover high priority
            url: $this->ticketUrl($ticket),
        );
    }

    /**
     * @param int $priority Pushover priority: -2 (lowest) to 2 (emergency)
     */
    private function send(string $recipient, string $title, string $message, int $priority = 0, ?string $url = null): void
    {
        $appToken = Setting::get('pushover_app_token');

        $payload = [
            'token' => $appToken,
            'user' => $recipient,
            'title' => $title,
            'message' => $message,
            'priority' => $priority,
        ];

        if ($url) {
            $payload['url'] = $url;
            $payload['url_title'] = 'Open in Admin';
        }

        try {
            $response = Http::asForm()->post(self::API_URL, $payload);
            $data = $response->json();

            if (($data['status'] ?? 0) !== 1) {
                Log::warning('Pushover ticket notification failed', [
                    'errors' => $data['errors'] ?? [],
                    'status' => $response->status(),
                ]);
            }
        } catch (\Exception $e) {
            Log::error('Pushover send exception', ['error' => $e->getMessage()]);
        }
    }

    private function mapPriority(?string $ticketPriority): int
    {
        return match (strtolower($ticketPriority ?? 'normal')) {
            'high', 'urgent', 'critical' => 1,
            'low' => -1,
            default => 0,
        };
    }

    private function ticketUrl(Ticket $ticket): string
    {
        return url("/admin/tickets/{$ticket->id}");
    }
}
