<?php

namespace Modules\Bms\Http\Controllers\Api;

use Illuminate\Http\Request;
use Modules\Bms\Entities\BmsBooking;
use Modules\Bms\Entities\BmsDocument;
use Modules\Bms\Entities\BmsLead;
use Modules\Bms\Services\Booking\BookingService;
use Modules\Bms\Services\Documents\DocumentService;

/**
 * Generated documents (contract / BEO / proposal / run-sheet). PDFs are
 * streamed through these authenticated endpoints — never a public URL.
 */
class DocumentController extends ApiController
{
    // ---- Employee (P2) ---------------------------------------------------

    public function generate(Request $request, int $id, string $type, DocumentService $docs)
    {
        $businessId = $this->authBusinessId($request);
        $booking = BmsBooking::where('business_id', $businessId)->with('halls')->findOrFail($id);
        $owner = $request->attributes->get('bms_owner');

        $doc = $docs->forBooking($booking, $type, $owner->id ?? null);

        // Let the client know a document is ready (matrix-routed, best effort).
        if (in_array($type, ['contract', 'proposal'], true)) {
            app(BookingService::class)->notifyContact(
                $booking, $type === 'contract' ? 'contract_sent' : 'document_ready',
                'Document ready', 'A new document is available for booking ' . $booking->booking_no . '.'
            );
        }

        return $this->ok(['document' => ['id' => $doc->id, 'type' => $doc->type, 'version' => $doc->version]]);
    }

    public function generateProposal(Request $request, int $id, DocumentService $docs)
    {
        $businessId = $this->authBusinessId($request);
        $lead = BmsLead::where('business_id', $businessId)->findOrFail($id);
        $owner = $request->attributes->get('bms_owner');

        $doc = $docs->forLead($lead, $owner->id ?? null);

        return $this->ok(['document' => ['id' => $doc->id, 'type' => $doc->type, 'version' => $doc->version]]);
    }

    public function listForBooking(Request $request, int $id, DocumentService $docs)
    {
        $businessId = $this->authBusinessId($request);
        BmsBooking::where('business_id', $businessId)->findOrFail($id);

        return $this->ok(['documents' => $docs->listForBooking($id)]);
    }

    public function download(Request $request, int $docId, DocumentService $docs)
    {
        $businessId = $this->authBusinessId($request);
        $doc = BmsDocument::where('business_id', $businessId)->findOrFail($docId);

        // Re-render in the requested language for inline view/print (EN/AR), else
        // stream the stored copy.
        $lang = $request->input('lang');
        if ($lang && $doc->booking_id) {
            $booking = BmsBooking::with('halls')->find($doc->booking_id);
            if ($booking) {
                $file = $docs->viewBooking($booking, $doc->type, $lang === 'ar' ? 'ar' : 'en');
                return response($file['contents'], 200, [
                    'Content-Type' => 'application/pdf',
                    'Content-Disposition' => 'inline; filename="' . $file['filename'] . '"',
                ]);
            }
        }

        $file = $docs->file($doc);
        return response($file['contents'], 200, [
            'Content-Type'        => $file['mime'],
            'Content-Disposition' => 'inline; filename="' . $file['filename'] . '"',
        ]);
    }

    // ---- Client (P3) -----------------------------------------------------

    public function clientDownload(Request $request, int $docId, DocumentService $docs)
    {
        $doc = $this->clientDoc($request, $docId);
        $file = $docs->file($doc);
        return response($file['contents'], 200, [
            'Content-Type'        => $file['mime'],
            'Content-Disposition' => 'inline; filename="' . $file['filename'] . '"',
        ]);
    }

    public function accept(Request $request, int $docId, DocumentService $docs)
    {
        $doc = $this->clientDoc($request, $docId);
        $docs->acceptContract($doc, $request->ip());

        return $this->ok(['accepted_at' => optional($doc->fresh()->accepted_at)->toIso8601String()]);
    }

    /** Resolve a document the authenticated client is allowed to see. */
    protected function clientDoc(Request $request, int $docId): BmsDocument
    {
        $owner = $request->attributes->get('bms_owner'); // App\Contact
        $businessId = (int) $request->attributes->get('bms_business_id');
        $doc = BmsDocument::where('business_id', $businessId)->findOrFail($docId);

        $contactId = $doc->booking_id
            ? BmsBooking::where('id', $doc->booking_id)->value('contact_id')
            : BmsLead::where('id', $doc->lead_id)->value('contact_id');

        abort_unless($owner && (int) $contactId === (int) $owner->id, 403, 'Forbidden');

        return $doc;
    }
}
