<?php

namespace App\Http\Controllers;

use App\Models\Invoice;
use App\Models\ServiceAsset;
use App\Models\ServiceLog;
use App\Models\ServiceTicket;
use App\Services\WhatsAppService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class HandoverController extends Controller
{
    private const DELIVERY_STATUSES = ['Ready', 'Cancelled'];

    // ── Tampilkan form serah terima ──────────────────────────

    public function show(ServiceTicket $ticket)
    {
        if (! in_array($ticket->status, self::DELIVERY_STATUSES, true)) {
            return back()->with('error', 'Delivery hanya bisa dilakukan untuk tiket berstatus "Ready" atau "Cancelled".');
        }

        if ($ticket->status === 'Cancelled' && $ticket->asset?->sig_exit) {
            return back()->with('error', 'Delivery pembatalan untuk tiket ini sudah pernah diproses sebelumnya.');
        }

        $ticket->load(['customer', 'asset', 'invoices']);

        $issuedInvoice = $ticket->invoices->firstWhere('status', Invoice::STATUS_ISSUED);

        if (! $issuedInvoice) {
            $draftOrReview = $ticket->invoices->whereIn('status', [Invoice::STATUS_DRAFT, Invoice::STATUS_REVIEW])->first();
            $msg = $draftOrReview
                ? 'Invoice untuk tiket ini belum diterbitkan (masih ' . $draftOrReview->status . '). Terbitkan invoice terlebih dahulu sebelum melakukan serah terima.'
                : 'Belum ada invoice untuk tiket ini. Buat dan terbitkan invoice terlebih dahulu sebelum melakukan serah terima.';
            return redirect()
                ->route('admin.invoices.create', ['service_ticket_id' => $ticket->id])
                ->with('error', $msg);
        }

        return view('handover.form', compact('ticket', 'issuedInvoice'));
    }

    // ── Proses serah terima ──────────────────────────────────

    public function store(Request $request, ServiceTicket $ticket)
    {
        if (! in_array($ticket->status, self::DELIVERY_STATUSES, true)) {
            return back()->with('error', 'Tiket tidak dalam status yang valid untuk delivery.');
        }

        if ($ticket->status === 'Cancelled' && $ticket->asset?->sig_exit) {
            return back()->with('error', 'Delivery pembatalan untuk tiket ini sudah pernah diproses sebelumnya.');
        }

        // Gate: harus ada invoice yang sudah diterbitkan
        $ticket->load('invoices');
        $hasIssuedInvoice = $ticket->invoices->contains('status', Invoice::STATUS_ISSUED);
        if (! $hasIssuedInvoice) {
            return back()->with('error', 'Invoice untuk tiket ini belum diterbitkan. Terbitkan invoice terlebih dahulu.');
        }

        $originalStatus = $ticket->status;

        $request->validate([
            'recipient_name' => ['required', 'string', 'max:255'],
            'photo_exit'     => ['nullable', 'image', 'max:5120'],
            'sig_exit'       => ['required', 'string'],   // base64 dari canvas — wajib
        ]);

        DB::transaction(function () use ($request, $ticket, $originalStatus) {
            // Simpan foto kondisi akhir (opsional)
            $photoExitPath = null;
            if ($request->hasFile('photo_exit')) {
                $photoExitPath = $request->file('photo_exit')
                    ->store("tickets/{$ticket->id}/exit", 'public');
            }

            // Simpan tanda tangan pengambil (wajib)
            $sigExitPath = $this->saveBase64Signature(
                $request->sig_exit,
                "tickets/{$ticket->id}/exit",
                'signature_exit'
            );

            // Perbarui atau buat service_assets
            $asset = $ticket->asset;
            if ($asset) {
                $asset->update([
                    'photo_exit'     => $photoExitPath ?? $asset->photo_exit,
                    'sig_exit'       => $sigExitPath,
                    'recipient_name' => $request->recipient_name,
                ]);
            } else {
                ServiceAsset::create([
                    'ticket_id'      => $ticket->id,
                    'photo_exit'     => $photoExitPath,
                    'sig_exit'       => $sigExitPath,
                    'recipient_name' => $request->recipient_name,
                ]);
            }

            $updatePayload = [];

            if ($originalStatus === 'Ready') {
                $updatePayload['status'] = 'Picked Up';
                $updatePayload['picked_up_at'] = now();
            } elseif (! $ticket->cancelled_at) {
                $updatePayload['cancelled_at'] = now();
            }

            if (! empty($updatePayload)) {
                $ticket->update($updatePayload);
            }

            // Catat log
            ServiceLog::create([
                'ticket_id' => $ticket->id,
                'user_id'   => auth()->id(),
                'note'      => $originalStatus === 'Ready'
                    ? "Delivery ke customer selesai. Diterima oleh \"{$request->recipient_name}\". Status: Picked Up."
                    : "Delivery pembatalan ke customer selesai. Diterima oleh \"{$request->recipient_name}\". Status: Cancelled.",
            ]);
        });

        // Kirim notifikasi WA otomatis (di luar transaksi agar tidak rollback jika WA gagal)
        $ticket->refresh();
        app(WhatsAppService::class)->notifyStatusChange($ticket);

        return redirect()
            ->route('nota.show', $ticket->ticket_code)
            ->with('success', 'Delivery berhasil diproses. Nota digital telah dibuat.');
    }

    // ─────────────────────── Helper ───────────────────────

    private function saveBase64Signature(string $base64, string $directory, string $filename): string
    {
        $data = preg_replace('/^data:image\/\w+;base64,/', '', $base64);
        $data = base64_decode($data);

        $path = "{$directory}/{$filename}.png";
        Storage::disk('public')->put($path, $data);

        return $path;
    }
}
