<?php

namespace App\Http\Controllers;

use App\Models\ServiceLog;
use App\Models\ServiceTicket;
use App\Services\WhatsAppService;
use Illuminate\Http\Request;

class TechnicianController extends Controller
{
    private const FINAL_STATUSES = ['Picked Up', 'Cancelled'];

    public function home()
    {
        $activeStatuses = ['Pending', 'Checking', 'Repairing', 'Ready'];

        $stats = [
            'pending' => ServiceTicket::where('status', 'Pending')->count(),
            'checking' => ServiceTicket::where('status', 'Checking')->count(),
            'repairing' => ServiceTicket::where('status', 'Repairing')->count(),
            'ready' => ServiceTicket::where('status', 'Ready')->count(),
            'picked_up_today' => ServiceTicket::whereDate('picked_up_at', today())->count(),
        ];

        $recentTickets = ServiceTicket::with('customer')
            ->whereIn('status', $activeStatuses)
            ->latest('updated_at')
            ->limit(8)
            ->get();

        return view('technician.home', compact('stats', 'recentTickets'));
    }

    public function index(Request $request)
    {
        $search = trim((string) $request->query('search', ''));
        $status = $request->query('status');

        $allowedStatuses = ['Pending', 'Checking', 'Repairing', 'Ready'];

        $query = ServiceTicket::with('customer')
            ->whereIn('status', $allowedStatuses)
            ->orderByRaw("FIELD(status, 'Pending','Checking','Repairing','Ready')")
            ->orderByDesc('updated_at');

        if ($status && in_array($status, $allowedStatuses, true)) {
            $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', function ($c) use ($search) {
                        $c->where('name', 'like', "%{$search}%");
                    });
            });
        }

        $tickets = $query->paginate(15)->withQueryString();

        return view('technician.index', compact('tickets', 'search', 'status'));
    }

    // ── Halaman scanner QR Code ───────────────────────────────

    public function scanner()
    {
        return view('technician.scanner');
    }

    // ── Manual entry via ticket_code ─────────────────────────

    public function scannerManual(Request $request)
    {
        $request->validate([
            'code' => ['required', 'string'],
        ]);

        $ticket = ServiceTicket::where('ticket_code', strtoupper(trim($request->code)))->firstOrFail();

        return redirect()->route('technician.book', $ticket);
    }

    // ── Service Book untuk satu tiket ────────────────────────

    public function servicebook(ServiceTicket $ticket)
    {
        $ticket->load([
            'customer',
            'asset',
            'logs' => fn ($q) => $q->with('user')->orderByDesc('created_at'),
        ]);

        $finalCheckTemplate = ServiceTicket::finalCheckTemplate($ticket->device_type);
        $finalCheckRequiredItems = ServiceTicket::finalCheckRequiredItems($ticket->device_type);
        $finalCheckMinimumPass = ServiceTicket::finalCheckMinimumPass($ticket->device_type);

        return view('technician.servicebook', compact(
            'ticket',
            'finalCheckTemplate',
            'finalCheckRequiredItems',
            'finalCheckMinimumPass'
        ));
    }

    // ── Tambah catatan log ───────────────────────────────────

    public function addLog(Request $request, ServiceTicket $ticket)
    {
        $request->validate([
            'note' => ['required', 'string', 'min:3', 'max:1000'],
        ]);

        $actorId = auth()->id();
        if (! $actorId) {
            return back()->with('error', 'Sesi login teknisi tidak valid. Silakan login ulang.');
        }

        ServiceLog::create([
            'ticket_id' => $ticket->id,
            'user_id'   => $actorId,
            'note'      => $request->note,
        ]);

        return back()->with('success', 'Catatan berhasil ditambahkan.');
    }

    public function saveDiagnosis(Request $request, ServiceTicket $ticket)
    {
        if (in_array($ticket->status, self::FINAL_STATUSES, true)) {
            return back()->with('error', 'Tiket final tidak dapat diubah.');
        }

        $actorId = auth()->id();
        if (! $actorId) {
            return back()->with('error', 'Sesi login teknisi tidak valid. Silakan login ulang.');
        }

        $data = $request->validate([
            'initial_diagnosis' => ['required', 'string', 'min:5', 'max:3000'],
            'diagnosis_findings' => ['nullable', 'string', 'max:3000'],
            'probable_cause' => ['required', 'string', 'min:3', 'max:3000'],
            'recommended_action' => ['required', 'string', 'min:3', 'max:3000'],
            'estimated_cost' => ['nullable', 'numeric', 'min:0'],
            'estimated_minutes' => ['nullable', 'integer', 'min:1', 'max:10080'],
        ]);

        $ticket->update([
            'initial_diagnosis' => $data['initial_diagnosis'],
            'diagnosis_findings' => $data['diagnosis_findings'] ?? null,
            'probable_cause' => $data['probable_cause'],
            'recommended_action' => $data['recommended_action'],
            'estimated_cost' => $data['estimated_cost'] ?? null,
            'estimated_minutes' => $data['estimated_minutes'] ?? null,
            'diagnosis_completed_at' => now(),
            'diagnosis_completed_by' => $actorId,
        ]);

        ServiceLog::create([
            'ticket_id' => $ticket->id,
            'user_id'   => $actorId,
            'note'      => 'Diagnosa awal dan rekomendasi perbaikan disimpan teknisi.',
        ]);

        return back()->with('success', 'Diagnosa awal dan rekomendasi berhasil disimpan.');
    }

    public function saveRepairExecution(Request $request, ServiceTicket $ticket)
    {
        if (in_array($ticket->status, self::FINAL_STATUSES, true)) {
            return back()->with('error', 'Tiket final tidak dapat diubah.');
        }

        $actorId = auth()->id();
        if (! $actorId) {
            return back()->with('error', 'Sesi login teknisi tidak valid. Silakan login ulang.');
        }

        $data = $request->validate([
            'repair_summary' => ['required', 'string', 'min:5', 'max:3000'],
            'parts_used' => ['nullable', 'string', 'max:3000'],
        ]);

        $ticket->update([
            'repair_summary' => $data['repair_summary'],
            'parts_used' => $data['parts_used'] ?? null,
        ]);

        ServiceLog::create([
            'ticket_id' => $ticket->id,
            'user_id'   => $actorId,
            'note'      => 'Catatan eksekusi perbaikan diperbarui teknisi.',
        ]);

        return back()->with('success', 'Eksekusi perbaikan berhasil disimpan.');
    }

    public function saveFinalCheck(Request $request, ServiceTicket $ticket)
    {
        if (in_array($ticket->status, self::FINAL_STATUSES, true)) {
            return back()->with('error', 'Tiket final tidak dapat diubah.');
        }

        $actorId = auth()->id();
        if (! $actorId) {
            return back()->with('error', 'Sesi login teknisi tidak valid. Silakan login ulang.');
        }

        $data = $request->validate([
            'final_check_notes' => ['required', 'string', 'min:5', 'max:3000'],
            'final_check_photo' => ['nullable', 'image', 'max:5120'],
            'final_check_items' => ['required', 'array', 'min:1'],
            'final_check_items.*' => ['string', 'max:255'],
        ]);

        $templateItems = ServiceTicket::finalCheckTemplate($ticket->device_type);
        $requiredItems = ServiceTicket::finalCheckRequiredItems($ticket->device_type);
        $minimumPass = ServiceTicket::finalCheckMinimumPass($ticket->device_type);

        $selectedItems = array_values(array_unique(array_intersect(
            $data['final_check_items'] ?? [],
            $templateItems
        )));

        if (count($selectedItems) < $minimumPass) {
            return back()->withErrors([
                'final_check_items' => "Minimal {$minimumPass} item harus lulus untuk {$ticket->device_type}.",
            ])->withInput();
        }

        $missingRequiredItems = array_values(array_diff($requiredItems, $selectedItems));
        if (! empty($missingRequiredItems)) {
            return back()->withErrors([
                'final_check_items' => 'Item inti wajib lulus terlebih dahulu: ' . implode(', ', $missingRequiredItems) . '.',
            ])->withInput();
        }

        $photoPath = $ticket->final_check_photo_path;
        if ($request->hasFile('final_check_photo')) {
            $photoPath = $request->file('final_check_photo')->store("tickets/{$ticket->id}/final-check", 'public');
        }

        $ticket->update([
            'final_check_notes' => $data['final_check_notes'],
            'final_check_items' => $selectedItems,
            'final_check_photo_path' => $photoPath,
            'final_check_passed_at' => now(),
            'final_check_passed_by' => $actorId,
        ]);

        ServiceLog::create([
            'ticket_id' => $ticket->id,
            'user_id'   => $actorId,
            'note'      => 'Final quality check diselesaikan teknisi (PASS).',
        ]);

        return back()->with('success', 'Final check berhasil disimpan dan dinyatakan lulus.');
    }

    // ── Ubah status tiket (Teknisi) ──────────────────────────

    public function updateStatus(Request $request, ServiceTicket $ticket)
    {
        $actorId = auth()->id();
        if (! $actorId) {
            return back()->with('error', 'Sesi login teknisi tidak valid. Silakan login ulang.');
        }

        $request->validate([
            'status' => ['required', 'in:Checking,Repairing,Ready'],
        ]);

        $newStatus = $request->status;

        // Validasi alur status
        $allowed = match ($ticket->status) {
            'Pending'   => ['Checking'],
            'Checking'  => ['Repairing'],
            'Repairing' => ['Ready'],
            default     => [],
        };

        if (! in_array($newStatus, $allowed)) {
            return back()->with('error', 'Perubahan status tidak diizinkan dari status saat ini.');
        }

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

        if ($newStatus === 'Repairing' && ! $ticket->diagnosis_completed_at) {
            return back()->with('error', 'Lengkapi diagnosa awal dan rekomendasi sebelum masuk 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.');
        }

        $payload = ['status' => $newStatus];
        if ($newStatus === 'Ready') {
            $payload['ready_at'] = now();
        }

        $ticket->update($payload);

        ServiceLog::create([
            'ticket_id' => $ticket->id,
            'user_id'   => $actorId,
            'note'      => "Status diubah ke \"{$newStatus}\" oleh teknisi.",
        ]);

        // Kirim notifikasi WA otomatis saat status = Ready
        if ($newStatus === 'Ready') {
            app(WhatsAppService::class)->notifyStatusChange($ticket);
        }

        return back()->with('success', "Status berhasil diubah ke {$newStatus}.");
    }
}
