<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\ServiceLog;
use App\Models\ServiceTicket;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class TicketController extends Controller
{
    /**
     * Daftar antrean servis dengan filter & pagination.
     */
    public function index(Request $request): View
    {
        $status   = $request->query('status');   // null = semua
        $search   = $request->query('search');
        $statuses = ServiceTicket::STATUSES;

        $query = ServiceTicket::with(['customer', 'invoices'])
            ->orderByRaw("FIELD(status, 'Pending','Checking','Repairing','Ready','Picked Up','Cancelled')")
            ->orderByDesc('created_at');

        if ($status && in_array($status, $statuses)) {
            $query->where('status', $status);
        }

        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('ticket_code', 'like', "%{$search}%")
                  ->orWhere('brand', 'like', "%{$search}%")
                  ->orWhere('model', 'like', "%{$search}%")
                  ->orWhereHas('customer', fn ($c) =>
                      $c->where('name', 'like', "%{$search}%")
                        ->orWhere('whatsapp', 'like', "%{$search}%")
                  );
            });
        }

        $tickets = $query->paginate(20)->withQueryString();
        $tickets->setCollection(
            $tickets->getCollection()->map(function (ServiceTicket $ticket) {
                $ticket->sla = $this->buildSlaMetrics($ticket);

                return $ticket;
            })
        );

        // Hitung jumlah per status untuk tab badge
        $counts = ServiceTicket::selectRaw('status, COUNT(*) as total')
            ->groupBy('status')
            ->pluck('total', 'status');

        // AJAX request (live search) → kembalikan partial saja
        if ($request->ajax()) {
            return view('admin.tickets._list', compact('tickets', 'statuses', 'status', 'search', 'counts'));
        }

        return view('admin.tickets.index', compact('tickets', 'statuses', 'status', 'search', 'counts'));
    }

    /**
    * Ubah status tiket secara cepat (Pending → Checking → Repairing → Ready → Picked Up).
     */
    public function updateStatus(Request $request, ServiceTicket $ticket): RedirectResponse
    {
        $request->validate([
            'status' => ['required', 'in:' . implode(',', ServiceTicket::STATUSES)],
        ]);

        $newStatus = $request->input('status');

        // Jangan biarkan ubah status lewat sini jika sudah Cancelled / Picked Up
        if (in_array($ticket->status, ['Cancelled', 'Picked Up'])) {
            return back()->with('error', 'Status tiket ini tidak dapat diubah lagi.');
        }

        $allowedTransitions = [
            'Pending'   => ['Checking'],
            'Checking'  => ['Repairing'],
            'Repairing' => ['Ready'],
            'Ready'     => ['Picked Up'],
        ];

        $allowed = $allowedTransitions[$ticket->status] ?? [];
        if (! in_array($newStatus, $allowed, true)) {
            return back()->with('error', 'Transisi status tidak valid dari status saat ini.');
        }

        if ($newStatus === 'Repairing' && ! $ticket->repair_approved_at) {
            return back()->with('error', 'Status "Repairing" hanya bisa dipilih setelah approval admin disimpan.');
        }

        if ($newStatus === 'Repairing' && ! $ticket->diagnosis_completed_at) {
            return back()->with('error', 'Lengkapi diagnosa awal teknisi sebelum memulai tahap perbaikan.');
        }

        if ($newStatus === 'Ready' && ! $ticket->final_check_passed_at) {
            return back()->with('error', 'Status "Ready" hanya bisa dipilih setelah final quality check dinyatakan lulus.');
        }

        $extraFields = [];
        if ($newStatus === 'Ready') {
            $extraFields['ready_at'] = now();
        }
        if ($newStatus === 'Picked Up') {
            $extraFields['picked_up_at'] = now();
        }

        $ticket->update(array_merge(['status' => $newStatus], $extraFields));

        ServiceLog::create([
            'ticket_id' => $ticket->id,
            'user_id'   => auth()->id() ?? 1,
            'note'      => "Status diubah menjadi: {$newStatus}.",
        ]);

        return back()->with('success', "Tiket {$ticket->ticket_code} diubah ke status \"{$newStatus}\".");
    }

    /**
     * Approval admin untuk memulai perbaikan.
     */
    public function approveRepair(Request $request, ServiceTicket $ticket): RedirectResponse
    {
        if (in_array($ticket->status, ['Cancelled', 'Picked Up'], true)) {
            return back()->with('error', 'Tiket final tidak bisa di-approve untuk perbaikan.');
        }

        if ($ticket->repair_approved_at) {
            return back()->with('success', 'Perbaikan untuk tiket ini sudah disetujui sebelumnya.');
        }

        $ticket->update([
            'repair_approved_at' => now(),
            'repair_approved_by' => auth()->id(),
        ]);

        ServiceLog::create([
            'ticket_id' => $ticket->id,
            'user_id'   => auth()->id() ?? 1,
            'note'      => 'Admin menyetujui perbaikan setelah konfirmasi pelanggan.',
        ]);

        return back()->with('success', "Approval perbaikan untuk {$ticket->ticket_code} berhasil disimpan.");
    }

    /**
     * Batalkan tiket dengan alasan.
     */
    public function cancel(Request $request, ServiceTicket $ticket): RedirectResponse
    {
        $request->validate([
            'cancel_reason' => ['required', 'string', 'min:5', 'max:500'],
        ]);

        if ($ticket->status === 'Cancelled') {
            return back()->with('error', 'Tiket ini sudah dibatalkan sebelumnya.');
        }

        if ($ticket->status === 'Picked Up') {
            return back()->with('error', 'Tiket yang sudah diambil tidak bisa dibatalkan.');
        }

        $ticket->update([
            'status'        => 'Cancelled',
            'cancel_reason' => $request->input('cancel_reason'),
            'cancelled_at'  => now(),
        ]);

        ServiceLog::create([
            'ticket_id' => $ticket->id,
            'user_id'   => auth()->id() ?? 1,
            'note'      => 'Tiket dibatalkan oleh admin. Alasan: ' . $request->input('cancel_reason'),
        ]);

        // Arahkan ke form buat invoice pembatalan agar kasir/admin langsung bisa tagih biaya diagnosa
        return redirect()
            ->route('admin.invoices.create', ['service_ticket_id' => $ticket->id])
            ->with('success', "Tiket {$ticket->ticket_code} berhasil dibatalkan. Silakan buat invoice pembatalan (isi Rp 0 jika tidak ada biaya).");
    }

    private function buildSlaMetrics(ServiceTicket $ticket): array
    {
        return [
            'diag_to_approval' => $this->durationMinutes($ticket->diagnosis_completed_at, $ticket->repair_approved_at),
            'approval_to_qc' => $this->durationMinutes($ticket->repair_approved_at, $ticket->final_check_passed_at),
            'qc_to_ready' => $this->durationMinutes($ticket->final_check_passed_at, $ticket->ready_at),
            'diag_to_ready' => $this->durationMinutes($ticket->diagnosis_completed_at, $ticket->ready_at),
        ];
    }

    private function durationMinutes($from, $to): ?int
    {
        if (! $from || ! $to) {
            return null;
        }

        return max($from->diffInMinutes($to), 0);
    }
}
