<?php

namespace App\Livewire\Dashboard;

use Illuminate\Support\Str;
use Illuminate\Support\Facades\Request;
use App\Models\Ticket;
use App\Models\TicketResponse;
use Exception;
use Livewire\Component;

class Support extends Component
{
    public $tickets = [];

    public $subject;

    public $message;

    public $response;

    public $list = false;

    public $open = 0;

    public $closed = 0;

    public function store(): void
    {
        $this->validate([
            'subject' => 'required|string|max:255',
            'message' => 'required|string',
        ]);

        try {
            $ticket = Ticket::query()->create([
                'user_id' => auth()->id(),
                'ticket_id' => strtoupper(Str::random(6)),
                'subject' => $this->subject,
                'message' => $this->message,
                'ip_address' => $this->getClientIp(),
                'last_response_at' => now(),
            ]);
            $this->dispatch('showAlert', ['type' => 'success', 'message' => 'Your ticket has been created successfully!']);
            $this->dispatch('closeModal');
            $this->reset(['subject', 'message']);
            $this->tickets = Ticket::with('responses')
                ->where('user_id', auth()->id())
                ->get();
        } catch (Exception) {
            $this->dispatch('showAlert', ['type' => 'error', 'message' => 'Something went wrong!']);
        }

    }

    public function reply($ticket_id): void
    {
        $this->validate([
            'response' => 'required|string',
        ]);

        try {

            if (! is_numeric($ticket_id)) {
                $this->dispatch('showAlert', ['type' => 'error', 'message' => 'Invalid ticket ID.']);

                return;
            }

            $ticket = Ticket::query()->find($ticket_id);
            if (! $ticket) {
                $this->dispatch('showAlert', ['type' => 'error', 'message' => 'Ticket not found.']);

                return;
            }

            TicketResponse::query()->create([
                'ticket_id' => $ticket_id,
                'user_id' => auth()->id(),
                'response' => $this->response,
                'ip_address' => $this->getClientIp(),
            ]);
            $ticket->last_response_at = now();
            $ticket->save();

            $this->dispatch('showAlert', ['type' => 'success', 'message' => 'Reply sent successfully!']);

            $this->reset(['response']);
            $this->tickets = Ticket::with('responses')
                ->where('user_id', auth()->id())
                ->get();

        } catch (Exception) {
            session()->flash('error', 'Something went wrong!');
        }

    }

    public function close($ticket_id): void
    {
        if (! is_numeric($ticket_id)) {
            $this->dispatch('showAlert', ['type' => 'error', 'message' => 'Invalid ticket ID.']);

            return;
        }
        $ticket = Ticket::query()->find($ticket_id);
        if (! $ticket) {
            $this->dispatch('showAlert', ['type' => 'error', 'message' => 'Ticket not found.']);

            return;
        }

        $ticket->status = 'closed';
        $ticket->save();
        $this->tickets = Ticket::with('responses')
            ->where('user_id', auth()->id())
            ->get();
        $this->updateTicketCounts();
        $this->dispatch('showAlert', ['type' => 'error', 'message' => 'This ticket has been closed!']);
    }

    public function mount(): void
    {
        $this->tickets = Ticket::with('responses')
            ->where('user_id', auth()->id())
            ->get();
        $this->updateTicketCounts();
    }

    public function updateTicketCounts(): void
    {
        $this->open = $this->tickets->filter(fn($ticket): bool => in_array($ticket->status, ['open', 'pending']))->count();

        $this->closed = $this->tickets->filter(fn($ticket): bool => $ticket->status === 'closed')->count();
    }

    protected function getClientIp()
    {
        // Cloudflare or other proxies may send the original client IP in X-Forwarded-For header
        $ip = Request::header('X-Forwarded-For');

        // X-Forwarded-For can contain a comma-separated list of IPs, so we need to get the first one
        if ($ip) {
            return explode(',', $ip)[0]; // Get the first IP in the list
        }

        // Fallback to the real IP if no X-Forwarded-For header
        return Request::ip();
    }

    public function render()
    {
        return view('livewire.dashboard.support')->layout('components.layouts.dashboard');
    }
}
