<?php

namespace Modules\ClinicCore\Http\Controllers;

use App\Transaction;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\ClinicCore\Entities\ClcWellnessPlan;
use Modules\ClinicCore\Entities\ClcWellnessPlanBenefit;
use Modules\ClinicCore\Entities\ClcWellnessSubscription;
use Modules\ClinicCore\Entities\ClcWellnessBenefitUsage;

/**
 * Wellness plans CRUD + subscribe action. Subscribing creates a parent
 * recurring transaction on the core engine (is_recurring=1, recur_interval=1
 * month/year). The existing pos:generateSubscriptionInvoices cron generates
 * actual invoices.
 */
class ClcWellnessController extends Controller
{
    use \Modules\ClinicCore\Http\Controllers\Traits\LogsClcActivity;

    private function biz() { return request()->session()->get('user.business_id'); }

    public function index()
    {
        if (!auth()->user()->can('clinic.view_wellness')) abort(403);
        $plans = ClcWellnessPlan::with('benefits')
            ->where('business_id', $this->biz())
            ->where('status', 'active')->orderBy('name')->get();
        // NOTE: view file is wellness/list.blade.php (not index.blade.php) —
        // AVG quarantined the original index.blade.php and left a persistent
        // path-lock that blocks recreation; list.blade.php is the same content.
        return view('clinicCore::wellness.list', compact('plans'));
    }

    public function storePlan(Request $request)
    {
        if (!auth()->user()->can('clinic.manage_wellness')) abort(403);
        $request->validate([
            'name'          => 'required|string|max:120',
            'price_monthly' => 'nullable|numeric|gte:0',
            'price_annual'  => 'nullable|numeric|gte:0',
            'product_id'    => 'nullable|integer',
            'description'   => 'nullable|string|max:500',
        ]);
        $plan = ClcWellnessPlan::create([
            'business_id'   => $this->biz(),
            'name'          => $request->name,
            'description'   => $request->description,
            'price_monthly' => $request->price_monthly,
            'price_annual'  => $request->price_annual,
            'product_id'    => $request->product_id,
            'status'        => 'active',
        ]);
        $this->drmLog('create', $plan);
        return response()->json(['success' => true, 'id' => $plan->id]);
    }

    public function addBenefit(Request $request, $planId)
    {
        if (!auth()->user()->can('clinic.manage_wellness')) abort(403);
        $request->validate([
            'kind'              => 'required|in:visits,vaccines,products,discount_pct',
            'label'             => 'required|string|max:120',
            'quantity_per_year' => 'nullable|numeric|gte:0',
            'value'             => 'nullable|numeric|gte:0',
        ]);
        $plan = ClcWellnessPlan::where('business_id', $this->biz())->findOrFail($planId);

        $b = ClcWellnessPlanBenefit::create(array_merge($request->only(['kind','label','quantity_per_year','value','notes']),
            ['plan_id' => $plan->id]));
        $this->drmLog('create', $b);
        return response()->json(['success' => true, 'id' => $b->id]);
    }

    /** Subscribe an owner+pet to a plan. Creates the recurring sell. */
    public function subscribe(Request $request)
    {
        if (!auth()->user()->can('clinic.manage_wellness')) abort(403);
        $request->validate([
            'plan_id'       => 'required|integer',
            'patient_id'        => 'required|integer',
            'contact_id'    => 'required|integer',
            'billing_cycle' => 'required|in:monthly,annual',
            'started_at'    => 'nullable|date',
        ]);

        $businessId = $this->biz();
        $plan = ClcWellnessPlan::where('business_id', $businessId)->findOrFail($request->plan_id);
        $price = $request->billing_cycle === 'annual' ? $plan->price_annual : $plan->price_monthly;
        if (!$price) {
            return response()->json(['success' => false, 'msg' => 'Plan has no price for the selected cycle.'], 422);
        }

        $started = $request->started_at ? Carbon::parse($request->started_at) : Carbon::today();

        // Create a recurring transaction on the core engine. The
        // pos:generateSubscriptionInvoices cron picks this up.
        $business = \App\Business::find($businessId);
        $locationId = $business?->locations()->first()->id ?? null;

        $recurring = Transaction::create([
            'business_id'         => $businessId,
            'location_id'         => $locationId,
            'type'                => 'sell',
            'status'              => 'final',
            'sub_status'          => null,
            'invoice_no'          => 'WP-' . strtoupper(uniqid()),
            'contact_id'          => $request->contact_id,
            'transaction_date'    => $started,
            'total_before_tax'    => $price,
            'final_total'         => $price,
            'is_recurring'        => 1,
            'recur_interval'      => 1,
            'recur_interval_type' => $request->billing_cycle === 'annual' ? 'years' : 'months',
            'created_by'          => auth()->id(),
        ]);

        $sub = ClcWellnessSubscription::create([
            'business_id'                  => $businessId,
            'contact_id'                   => $request->contact_id,
            'patient_id'                       => $request->patient_id,
            'plan_id'                      => $plan->id,
            'status'                       => 'active',
            'billing_cycle'                => $request->billing_cycle,
            'started_at'                   => $started,
            'renews_at'                    => $request->billing_cycle === 'annual'
                ? $started->copy()->addYear()
                : $started->copy()->addMonth(),
            'erp_recurring_transaction_id' => $recurring->id,
            'created_by'                   => auth()->id(),
        ]);
        $this->drmLog('create', $sub, ['plan' => $plan->name]);

        return response()->json(['success' => true, 'subscription_id' => $sub->id, 'recurring_txn_id' => $recurring->id]);
    }

    public function cancel(Request $request, $subId)
    {
        if (!auth()->user()->can('clinic.manage_wellness')) abort(403);
        $sub = ClcWellnessSubscription::where('business_id', $this->biz())->findOrFail($subId);
        $sub->update(['status' => 'cancelled', 'ended_at' => now()]);

        // Stop the recurring transaction.
        if ($sub->erp_recurring_transaction_id) {
            \App\Transaction::where('id', $sub->erp_recurring_transaction_id)
                ->update(['recur_stopped_on' => now()]);
        }
        $this->drmLog('update', $sub, ['action' => 'cancelled']);
        return response()->json(['success' => true]);
    }

    /** AJAX: active subscription for a (contact, pet) — used by redemption hooks. */
    public function active(Request $request)
    {
        if (!auth()->user()->can('clinic.view_wellness')) abort(403);
        $sub = ClcWellnessSubscription::with('plan.benefits')
            ->where('business_id', $this->biz())
            ->where('contact_id', $request->contact_id)
            ->where('patient_id', $request->patient_id)
            ->where('status', 'active')
            ->latest('id')->first();
        return response()->json(['data' => $sub]);
    }

    /** Redeem a benefit usage row (called from the redemption hook). */
    public function redeem(Request $request)
    {
        if (!auth()->user()->can('clinic.manage_wellness')) abort(403);
        $request->validate([
            'subscription_id' => 'required|integer',
            'benefit_id'      => 'required|integer',
            'qty'             => 'nullable|numeric|gt:0',
            'discounted_amount' => 'nullable|numeric|gte:0',
            'source_type'     => 'nullable|string|max:30',
            'source_id'       => 'nullable|integer',
            'notes'           => 'nullable|string|max:255',
        ]);
        $sub = ClcWellnessSubscription::where('business_id', $this->biz())->findOrFail($request->subscription_id);
        if ($sub->status !== 'active') {
            return response()->json(['success' => false, 'msg' => 'Subscription not active.'], 422);
        }
        $row = ClcWellnessBenefitUsage::create([
            'subscription_id'   => $sub->id,
            'benefit_id'        => $request->benefit_id,
            'used_at'           => now(),
            'qty'               => $request->qty ?? 1,
            'discounted_amount' => $request->discounted_amount,
            'source_type'       => $request->source_type,
            'source_id'         => $request->source_id,
            'notes'             => $request->notes,
        ]);
        return response()->json(['success' => true, 'usage_id' => $row->id]);
    }
}
