<?php

namespace App\Http\Controllers\Portal;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Services\ZtApiService;
use App\Services\WhmcsSupportService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

class TicketController extends Controller
{
    public function __construct(private readonly ZtApiService $api, private readonly WhmcsSupportService $support) {}

    public function index(): View
    {
        $user = Auth::user();
        $departments = $this->api->supportDepartments();
        $statuses = $this->api->supportStatuses();
        $tickets = $this->api->tickets($this->whmcsClientId($user), $user->email, 25);

        return view('client.support', [
            'departments' => $departments['departments'] ?? [],
            'departmentsError' => ($departments['ok'] ?? false) ? null : ($departments['message'] ?? 'Could not load support departments.'),
            'statuses' => $statuses['statuses'] ?? [],
            'tickets' => $tickets['tickets'] ?? [],
            'ticketsError' => ($tickets['ok'] ?? false) ? null : ($tickets['message'] ?? 'Could not load tickets.'),
            'ticket' => null,
            'ticketError' => null,
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $user = $request->user();
        $data = $request->validate([
            'deptid' => ['required', 'integer', 'min:1'],
            'subject' => ['required', 'string', 'max:255'],
            'message' => ['required', 'string', 'max:5000'],
            'priority' => ['required', 'in:Low,Medium,High'],
            'attachments' => ['nullable', 'array', 'max:3'],
            'attachments.*' => ['file', 'mimes:jpg,jpeg,png,webp,pdf,txt,zip', 'max:5120'],
        ]);

        $payload = [
            'deptid' => (int) $data['deptid'],
            'subject' => $data['subject'],
            'message' => $data['message'],
            'priority' => $data['priority'],
            'attachments' => $this->support->encodeAttachments($request->file('attachments', [])),
        ] + $this->requestorPayload($user);

        $result = $this->api->openTicket($payload);

        if (! ($result['ok'] ?? false)) {
            return back()->withErrors(['ticket' => $result['message'] ?? 'Ticket could not be opened.'])->withInput();
        }

        $ticketId = Arr::get($result, 'response.id');

        if ($ticketId) {
            return redirect()->route('client.support.show', $ticketId)->with('status', 'Ticket opened successfully.');
        }

        return redirect()->route('client.support')->with('status', 'Ticket opened successfully.');
    }

    public function show(int|string $ticket): View
    {
        $user = Auth::user();
        $departments = $this->api->supportDepartments();
        $tickets = $this->api->tickets($this->whmcsClientId($user), $user->email, 25);
        $ticketResult = $this->api->ticket($ticket);
        $ticketData = $ticketResult['ticket'] ?? null;
        $ticketError = ($ticketResult['ok'] ?? false) ? null : ($ticketResult['message'] ?? 'Could not load this ticket.');

        if ($ticketData && ! $this->ticketBelongsToUser($ticketData, $user)) {
            abort(403);
        }

        return view('client.support', [
            'departments' => $departments['departments'] ?? [],
            'departmentsError' => ($departments['ok'] ?? false) ? null : ($departments['message'] ?? 'Could not load support departments.'),
            'statuses' => [],
            'tickets' => $tickets['tickets'] ?? [],
            'ticketsError' => ($tickets['ok'] ?? false) ? null : ($tickets['message'] ?? 'Could not load tickets.'),
            'ticket' => $ticketData,
            'ticketError' => $ticketError,
        ]);
    }

    public function reply(Request $request, int|string $ticket): RedirectResponse
    {
        $user = $request->user();
        $ticketResult = $this->api->ticket($ticket);
        $ticketData = $ticketResult['ticket'] ?? null;

        if (! ($ticketResult['ok'] ?? false) || ! $ticketData) {
            return back()->withErrors(['reply' => $ticketResult['message'] ?? 'Could not load this ticket.']);
        }

        if (! $this->ticketBelongsToUser($ticketData, $user)) {
            abort(403);
        }

        $data = $request->validate([
            'message' => ['required', 'string', 'max:5000'],
            'attachments' => ['nullable', 'array', 'max:3'],
            'attachments.*' => ['file', 'mimes:jpg,jpeg,png,webp,pdf,txt,zip', 'max:5120'],
        ]);

        $payload = [
            'ticketid' => (int) Arr::get($ticketData, 'ticketid', $ticket),
            'message' => $data['message'],
            'attachments' => $this->support->encodeAttachments($request->file('attachments', [])),
        ] + $this->requestorPayload($user);

        $result = $this->api->addTicketReply($payload);

        if (! ($result['ok'] ?? false)) {
            return back()->withErrors(['reply' => $result['message'] ?? 'Reply could not be added.'])->withInput();
        }

        return redirect()->route('client.support.show', Arr::get($ticketData, 'ticketid', $ticket))->with('status', 'Reply added successfully.');
    }

    protected function requestorPayload(User $user): array
    {
        $clientId = $this->whmcsClientId($user);

        if ($clientId) {
            return ['clientid' => $clientId];
        }

        return [
            'name' => $user->displayName(),
            'email' => $user->email,
        ];
    }

    protected function whmcsClientId(User $user): ?int
    {
        $clientId = (int) ($user->whmcs_client_id ?? 0);

        return $clientId > 0 ? $clientId : null;
    }

    protected function ticketBelongsToUser(array $ticket, User $user): bool
    {
        $clientId = $this->whmcsClientId($user);
        $ticketUserId = (int) Arr::get($ticket, 'userid', 0);

        if ($clientId && $ticketUserId > 0) {
            return $ticketUserId === $clientId;
        }

        $ticketEmail = strtolower(trim((string) Arr::get($ticket, 'email', Arr::get($ticket, 'requestor_email', ''))));

        return $ticketEmail !== '' && $ticketEmail === strtolower(trim($user->email));
    }
}
