<?php

namespace App\Http\Controllers\Tenant;

use App\Domain\Clinical\TreatmentPlanService;
use App\Domain\Pdf\TreatmentPlanPdf;
use App\Domain\WhatsApp\WhatsAppManager;
use App\Domain\Files\PatientFileService;
use App\Enums\WaTemplateKey;
use Illuminate\Support\Facades\Storage;
use App\Enums\TreatmentPlanStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\PlanItemRequest;
use App\Http\Requests\TreatmentPlanRequest;
use App\Models\Dentist;
use App\Models\Patient;
use App\Models\Procedure;
use App\Models\TreatmentPlan;
use App\Models\TreatmentPlanItem;
use Illuminate\Http\Request;

class TreatmentPlanController extends Controller
{
    public function __construct(protected TreatmentPlanService $service)
    {
    }

    public function index()
    {
        $this->authorize('viewAny', TreatmentPlan::class);

        return view('treatment-plans.index', [
            'plans' => TreatmentPlan::with(['patient:id,full_name', 'dentist:id,name'])
                ->withCount('items')
                ->when(request('status'), fn ($q, $s) => $q->where('status', $s))
                ->latest()->paginate(25)->withQueryString(),
            'statuses' => TreatmentPlanStatus::cases(),
        ]);
    }

    public function store(TreatmentPlanRequest $request)
    {
        $plan = TreatmentPlan::create($request->validated() + [
            'created_by' => $request->user()->id,
        ]);

        return redirect()->route('tenant.treatment-plans.show', $plan)
            ->with('status', __('Treatment plan created.'));
    }

    public function show(TreatmentPlan $treatment_plan)
    {
        $this->authorize('view', $treatment_plan);

        return view('treatment-plans.show', [
            'plan' => $treatment_plan->load(['patient', 'dentist', 'items.procedure', 'items.appointment']),
            'procedures' => Procedure::active()->orderBy('category')->get(),
            'dentists' => Dentist::active()->get(),
            'statuses' => TreatmentPlanStatus::cases(),
        ]);
    }

    public function update(Request $request, TreatmentPlan $treatment_plan)
    {
        $this->authorize('update', $treatment_plan);

        $data = $request->validate([
            'title' => ['sometimes', 'string', 'max:190'],
            'discount_amount' => ['sometimes', 'integer', 'min:0'],
            'notes' => ['nullable', 'string', 'max:2000'],
        ]);

        abort_unless(
            ($data['discount_amount'] ?? 0) <= $treatment_plan->totalGross(),
            422, __('Discount cannot exceed the plan total.')
        );

        $treatment_plan->update($data);

        return back()->with('status', __('Changes saved.'));
    }

    public function updateStatus(Request $request, TreatmentPlan $treatment_plan)
    {
        $this->authorize('update', $treatment_plan);

        $request->validate(['status' => ['required', 'string']]);
        $to = TreatmentPlanStatus::from($request->status);

        $this->service->changeStatus($treatment_plan, $to);

        return back()->with('status', __('Status updated.'));
    }

    public function addItem(PlanItemRequest $request, TreatmentPlan $treatment_plan)
    {
        $this->authorize('update', $treatment_plan);
        $this->service->addItem($treatment_plan, $request->validated(), $request->user()->id);

        return back()->with('status', __('Item added.'));
    }

    public function completeItem(Request $request, TreatmentPlan $treatment_plan, TreatmentPlanItem $item)
    {
        $this->authorize('update', $treatment_plan);
        abort_unless($item->treatment_plan_id === $treatment_plan->id, 404);

        $this->service->completeItem($item, $request->user()->id);

        return back()->with('status', __('Item completed — chart updated.'));
    }

    public function cancelItem(TreatmentPlan $treatment_plan, TreatmentPlanItem $item)
    {
        $this->authorize('update', $treatment_plan);
        abort_unless($item->treatment_plan_id === $treatment_plan->id, 404);

        $this->service->cancelItem($item);

        return back()->with('status', __('Item cancelled.'));
    }

    public function pdf(TreatmentPlan $treatment_plan, TreatmentPlanPdf $pdf)
    {
        $this->authorize('view', $treatment_plan);

        return response($pdf->render($treatment_plan), 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'inline; filename="'.$pdf->filename($treatment_plan).'"',
        ]);
    }

    /** v2.1-C: attach the plan PDF to a WhatsApp message. */
    public function sendPdf(TreatmentPlan $treatment_plan, TreatmentPlanPdf $pdf, WhatsAppManager $wa)
    {
        $this->authorize('view', $treatment_plan);
        $treatment_plan->loadMissing('patient');

        $filename = $pdf->filename($treatment_plan);
        $path = 'tenants/'.$treatment_plan->tenant_id.'/wa/'.$filename;
        Storage::disk(PatientFileService::DISK)->put($path, $pdf->render($treatment_plan));

        $wa->queueTemplate(
            patient: $treatment_plan->patient,
            templateKey: WaTemplateKey::TreatmentPlan->value,
            related: $treatment_plan,
            mediaPath: $path,
            mediaMime: 'application/pdf',
            mediaFilename: $filename,
            createdBy: auth()->id(),
        );

        return back()->with('status', __('Treatment plan sent on WhatsApp.'));
    }
}
