<?php

namespace Modules\VetClinic\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\VetClinic\Entities\VcReminderSetting;
use Modules\VetClinic\Entities\VcReminderTemplate;
use Modules\VetClinic\Entities\VcReminderLog;
use Modules\VetClinic\Entities\VcVaccination;
use Modules\VetClinic\Entities\VcPetOwnerDetail;
use Carbon\Carbon;

class VcReminderController extends Controller
{
    public function settings()
    {
        if (!auth()->user()->can('vet_clinic.access_settings')) {
            abort(403, 'Unauthorized action.');
        }

        $businessId = request()->session()->get('user.business_id');
        $settings   = VcReminderSetting::forBusiness($businessId);
        $lastLog    = VcReminderLog::where('business_id', $businessId)->latest('sent_at')->first();
        $sentToday  = VcReminderLog::where('business_id', $businessId)
            ->whereDate('sent_at', today())
            ->where('status', 'sent')
            ->count();

        return view('vetClinic::reminders.settings', compact('settings', 'lastLog', 'sentToday'));
    }

    public function saveSettings(Request $request)
    {
        if (!auth()->user()->can('vet_clinic.access_settings')) {
            abort(403, 'Unauthorized action.');
        }

        $request->validate([
            'days_before_due'           => 'required|integer|min:1|max:90',
            'overdue_reminder_interval' => 'required|integer|min:1|max:30',
            'max_reminders_per_vaccine' => 'required|integer|min:1|max:10',
            'schedule_time'             => 'required|date_format:H:i',
        ]);

        $businessId = request()->session()->get('user.business_id');
        $settings   = VcReminderSetting::forBusiness($businessId);
        $settings->update([
            'is_enabled'                => $request->boolean('is_enabled'),
            'days_before_due'           => $request->days_before_due,
            'send_overdue'              => $request->boolean('send_overdue'),
            'overdue_reminder_interval' => $request->overdue_reminder_interval,
            'max_reminders_per_vaccine' => $request->max_reminders_per_vaccine,
            'email_enabled'             => $request->boolean('email_enabled'),
            'wa_enabled'                => $request->boolean('wa_enabled'),
            'sms_enabled'               => $request->boolean('sms_enabled'),
            'schedule_time'             => $request->schedule_time,
        ]);

        return redirect()->route('vc.reminders.settings')
            ->with('status', ['success' => 1, 'msg' => __('vetClinic::lang.updated_successfully')]);
    }

    public function templates()
    {
        if (!auth()->user()->can('vet_clinic.access_settings')) {
            abort(403, 'Unauthorized action.');
        }

        $businessId = request()->session()->get('user.business_id');
        $templates  = VcReminderTemplate::where(function ($q) use ($businessId) {
            $q->where('business_id', $businessId)->orWhereNull('business_id');
        })->orderBy('type')->get();

        $variables = VcReminderTemplate::availableVariables();

        return view('vetClinic::reminders.templates', compact('templates', 'variables'));
    }

    public function editTemplate($id)
    {
        if (!auth()->user()->can('vet_clinic.access_settings')) {
            abort(403, 'Unauthorized action.');
        }

        $businessId = request()->session()->get('user.business_id');
        $template   = VcReminderTemplate::where(function ($q) use ($businessId) {
            $q->where('business_id', $businessId)->orWhereNull('business_id');
        })->findOrFail($id);

        return response()->json($template);
    }

    public function updateTemplate(Request $request, $id)
    {
        if (!auth()->user()->can('vet_clinic.access_settings')) {
            abort(403, 'Unauthorized action.');
        }

        $request->validate([
            'name'    => 'required|string|max:100',
            'body'    => 'required|string',
            'subject' => 'nullable|string|max:255',
        ]);

        $businessId = request()->session()->get('user.business_id');
        $template   = VcReminderTemplate::where(function ($q) use ($businessId) {
            $q->where('business_id', $businessId)->orWhereNull('business_id');
        })->findOrFail($id);

        // System default being customised — create a business-specific copy
        if ($template->is_system_default && $template->business_id === null) {
            VcReminderTemplate::create([
                'business_id'       => $businessId,
                'type'              => $template->type,
                'name'              => $request->name,
                'subject'           => $request->subject,
                'body'              => $request->body,
                'is_active'         => true,
                'is_system_default' => false,
            ]);
        } else {
            $template->update([
                'name'      => $request->name,
                'subject'   => $request->subject,
                'body'      => $request->body,
                'is_active' => $request->boolean('is_active', true),
            ]);
        }

        return response()->json(['success' => true, 'msg' => __('vetClinic::lang.updated_successfully')]);
    }

    public function sendNow(Request $request)
    {
        if (!auth()->user()->can('vet_clinic.manage_vaccinations')) {
            abort(403, 'Unauthorized action.');
        }

        $businessId = request()->session()->get('user.business_id');
        $result     = $this->dispatchReminders($businessId);

        return response()->json([
            'success' => true,
            'msg'     => "Reminders processed: {$result['sent']} sent, {$result['skipped']} skipped, {$result['failed']} failed.",
            'result'  => $result,
        ]);
    }

    public function sendManual(Request $request, $vaccinationId)
    {
        if (!auth()->user()->can('vet_clinic.manage_vaccinations')) {
            abort(403, 'Unauthorized action.');
        }

        $businessId = request()->session()->get('user.business_id');
        $vax        = VcVaccination::with(['pet.owner', 'vaccineType'])
            ->where('business_id', $businessId)->findOrFail($vaccinationId);

        $result = $this->sendReminderForVaccination($vax, $businessId, true);

        if ($result['sent']) {
            return response()->json(['success' => true, 'msg' => "Reminder sent to {$result['sent_to']}"]);
        }

        return response()->json(['success' => false, 'msg' => $result['reason'] ?? 'Could not send reminder.']);
    }

    public function dispatchReminders(int $businessId): array
    {
        $settings = VcReminderSetting::forBusiness($businessId);
        if (!$settings->is_enabled) {
            return ['sent' => 0, 'skipped' => 0, 'failed' => 0, 'reason' => 'Reminders disabled'];
        }
        $smsOn = (bool) ($settings->sms_enabled ?? false);
        if (!$settings->email_enabled && !$smsOn) {
            return ['sent' => 0, 'skipped' => 0, 'failed' => 0, 'reason' => 'No reminder channel enabled'];
        }

        $today  = Carbon::today();
        $cutoff = $today->copy()->addDays($settings->days_before_due);

        $query = VcVaccination::with(['pet.owner', 'vaccineType'])
            ->where('business_id', $businessId)
            ->where('taken_status', 'not_taken')
            ->where('administered_date', '<=', $cutoff);

        if (!$settings->send_overdue) {
            $query->where('administered_date', '>=', $today);
        }

        $sent = 0; $skipped = 0; $failed = 0;
        foreach ($query->get() as $vax) {

            // Email channel (existing behaviour).
            if ($settings->email_enabled) {
                $r = $this->sendReminderForVaccination($vax, $businessId, false, $settings);
                if ($r['sent'])       { $sent++; }
                elseif ($r['failed']) { $failed++; }
                else                  { $skipped++; }
            }

            // SMS channel — added so vet reminders ride the existing core SMS
            // gateway (per-business sms_settings configured under Business
            // settings → Notification settings).
            if ($smsOn) {
                $r = $this->sendSmsReminderForVaccination($vax, $businessId, false, $settings);
                if ($r['sent'])       { $sent++; }
                elseif ($r['failed']) { $failed++; }
                else                  { $skipped++; }
            }
        }

        return compact('sent', 'skipped', 'failed');
    }

    /**
     * SMS counterpart of sendReminderForVaccination. Templates of type
     * 'sms_due' / 'sms_overdue' are rendered with the same {{vars}} and
     * dispatched via the core Util::sendSms($data) using the business's
     * sms_settings — no vet-specific gateway is built.
     */
    public function sendSmsReminderForVaccination(
        VcVaccination $vax,
        int $businessId,
        bool $force = false,
        ?VcReminderSetting $settings = null
    ): array {
        $owner  = optional($vax->pet)->owner;
        $mobile = optional($owner)->mobile;
        if (!$mobile) {
            return ['sent' => false, 'failed' => false, 'reason' => 'No mobile number'];
        }

        $settings = $settings ?? VcReminderSetting::forBusiness($businessId);

        if (!$force && VcReminderLog::countFor($vax->id, 'sms') >= $settings->max_reminders_per_vaccine) {
            return ['sent' => false, 'failed' => false, 'reason' => 'Max reminders reached'];
        }
        if (!$force && VcReminderLog::sentToday($vax->id, 'sms')) {
            return ['sent' => false, 'failed' => false, 'reason' => 'Already sent today'];
        }

        $today     = Carbon::today();
        $adminDate = $vax->administered_date ? Carbon::parse($vax->administered_date) : null;
        $isOverdue = $adminDate && $adminDate->lt($today);
        $type      = $isOverdue ? 'sms_overdue' : 'sms_due';

        $tpl = VcReminderTemplate::activeFor($businessId, $type);
        if (!$tpl) {
            return ['sent' => false, 'failed' => false, 'reason' => 'No active template for type: ' . $type];
        }

        $business = \App\Business::find($businessId);

        // Core SMS engine refuses to send without sms_settings configured.
        $smsSettings = $business->sms_settings ?? null;
        if (empty($smsSettings) || !is_array($smsSettings)) {
            return ['sent' => false, 'failed' => false, 'reason' => 'Business SMS settings not configured'];
        }

        $daysUntilDue = $adminDate ? (int) $today->diffInDays($adminDate, false) : null;
        $vars = [
            '{{owner_name}}'     => optional($owner)->name ?? '',
            '{{pet_name}}'       => optional($vax->pet)->petname ?? '',
            '{{pet_species}}'    => optional($vax->pet)->species ?? '',
            '{{vaccine_name}}'   => optional($vax->vaccineType)->name ?? '',
            '{{due_date}}'       => $adminDate ? $adminDate->format('d M Y') : '',
            '{{days_until_due}}' => $daysUntilDue !== null
                ? abs($daysUntilDue) . ($daysUntilDue < 0 ? ' days overdue' : ' days')
                : '',
            '{{clinic_name}}'    => optional($business)->name ?? '',
            '{{clinic_phone}}'   => optional($business)->mobile ?? '',
            '{{clinic_email}}'   => optional($business)->email ?? '',
            '{{clinic_address}}' => optional($business)->city ?? '',
        ];

        $body = VcReminderTemplate::render($tpl->body, $vars);

        try {
            app(\App\Utils\Util::class)->sendSms([
                'sms_settings'  => $smsSettings,
                'mobile_number' => $mobile,
                'sms_body'      => $body,
            ]);

            VcReminderLog::create([
                'business_id'    => $businessId,
                'vaccination_id' => $vax->id,
                'contact_id'     => optional($owner)->id ?? 0,
                'pet_id'         => $vax->pet_id,
                'channel'        => 'sms',
                'template_type'  => $type,
                'sent_to'        => $mobile,
                'status'         => 'sent',
                'sent_at'        => now(),
            ]);

            $vax->update(['reminder_sent' => true]);

            return ['sent' => true, 'failed' => false, 'sent_to' => $mobile];
        } catch (\Exception $e) {
            VcReminderLog::create([
                'business_id'    => $businessId,
                'vaccination_id' => $vax->id,
                'contact_id'     => optional($owner)->id ?? 0,
                'pet_id'         => $vax->pet_id,
                'channel'        => 'sms',
                'template_type'  => $type,
                'sent_to'        => $mobile,
                'status'         => 'failed',
                'error_message'  => $e->getMessage(),
                'sent_at'        => now(),
            ]);

            return ['sent' => false, 'failed' => true, 'reason' => $e->getMessage()];
        }
    }

    public function sendReminderForVaccination(VcVaccination $vax, int $businessId, bool $force = false, ?VcReminderSetting $settings = null): array
    {
        $owner = optional($vax->pet)->owner;
        $email = optional($owner)->email;
        if (!$email) {
            return ['sent' => false, 'failed' => false, 'reason' => 'No email address'];
        }

        if (!$force) {
            $detail = VcPetOwnerDetail::where('contact_id', optional($owner)->id)->first();
            if (!$detail || !$detail->email_confirmed) {
                return ['sent' => false, 'failed' => false, 'reason' => 'Email not confirmed'];
            }
        }

        $settings = $settings ?? VcReminderSetting::forBusiness($businessId);

        if (!$force && VcReminderLog::countFor($vax->id, 'email') >= $settings->max_reminders_per_vaccine) {
            return ['sent' => false, 'failed' => false, 'reason' => 'Max reminders reached'];
        }

        if (!$force && VcReminderLog::sentToday($vax->id, 'email')) {
            return ['sent' => false, 'failed' => false, 'reason' => 'Already sent today'];
        }

        $today     = Carbon::today();
        $adminDate = $vax->administered_date ? Carbon::parse($vax->administered_date) : null;
        $isOverdue = $adminDate && $adminDate->lt($today);
        $type      = $isOverdue ? 'email_overdue' : 'email_due';

        $tpl = VcReminderTemplate::activeFor($businessId, $type);
        if (!$tpl) {
            return ['sent' => false, 'failed' => false, 'reason' => 'No active template for type: ' . $type];
        }

        $business     = \App\Business::find($businessId);
        $daysUntilDue = $adminDate ? (int) $today->diffInDays($adminDate, false) : null;

        $vars = [
            '{{owner_name}}'     => optional($owner)->name ?? '',
            '{{pet_name}}'       => optional($vax->pet)->petname ?? '',
            '{{pet_species}}'    => optional($vax->pet)->species ?? '',
            '{{vaccine_name}}'   => optional($vax->vaccineType)->name ?? '',
            '{{due_date}}'       => $adminDate ? $adminDate->format('d M Y') : '',
            '{{days_until_due}}' => $daysUntilDue !== null
                ? abs($daysUntilDue) . ($daysUntilDue < 0 ? ' days overdue' : ' days')
                : '',
            '{{clinic_name}}'    => optional($business)->name ?? '',
            '{{clinic_phone}}'   => optional($business)->mobile ?? '',
            '{{clinic_email}}'   => optional($business)->email ?? '',
            '{{clinic_address}}' => optional($business)->city ?? '',
        ];

        $subject = VcReminderTemplate::render($tpl->subject ?? 'Vaccination Reminder', $vars);
        $body    = VcReminderTemplate::render($tpl->body, $vars);

        try {
            \Mail::raw($body, function ($msg) use ($email, $owner, $subject) {
                $msg->to($email, optional($owner)->name)->subject($subject);
            });

            VcReminderLog::create([
                'business_id'    => $businessId,
                'vaccination_id' => $vax->id,
                'contact_id'     => optional($owner)->id ?? 0,
                'pet_id'         => $vax->pet_id,
                'channel'        => 'email',
                'template_type'  => $type,
                'sent_to'        => $email,
                'status'         => 'sent',
                'sent_at'        => now(),
            ]);

            $vax->update(['reminder_sent' => true]);

            return ['sent' => true, 'failed' => false, 'sent_to' => $email];
        } catch (\Exception $e) {
            VcReminderLog::create([
                'business_id'    => $businessId,
                'vaccination_id' => $vax->id,
                'contact_id'     => optional($owner)->id ?? 0,
                'pet_id'         => $vax->pet_id,
                'channel'        => 'email',
                'template_type'  => $type,
                'sent_to'        => $email,
                'status'         => 'failed',
                'error_message'  => $e->getMessage(),
                'sent_at'        => now(),
            ]);

            return ['sent' => false, 'failed' => true, 'reason' => $e->getMessage()];
        }
    }
}
