<?php

namespace App\Livewire;

use App\Livewire\Concerns\ResolvesCustomer;
use App\Models\Instance;
use LivewireUI\Modal\ModalComponent;

/**
 * Cancel the customer's package (R5). Per the founder's decision: effective at
 * the end of the billing term, irreversible once confirmed; at term end the
 * customer receives a finished data export, then the instance is deprovisioned
 * (both mocked for now). Requires typing the instance subdomain to confirm.
 */
class ConfirmCancelPackage extends ModalComponent
{
    use ResolvesCustomer;

    public string $confirmName = '';

    public function cancelPackage()
    {
        $customer = $this->customer();
        // Target the ACTIVE package explicitly — a newer failed/deprovisioned
        // record must not shadow an older active instance (v1: one active/customer).
        $instance = $customer?->instances()->where('status', 'active')->latest('id')->first();

        if ($instance === null) {
            // Explain rather than silently closing: no customer behind this login
            // (e.g. an operator account) or no active package to cancel.
            $this->addError('confirmName', __($customer === null ? 'dashboard.no_customer_action' : 'settings.no_package'));

            return null;
        }

        // Typed confirmation must match the instance subdomain.
        if (trim($this->confirmName) !== (string) $instance->subdomain) {
            $this->addError('confirmName', __('settings.cancel_mismatch'));

            return;
        }

        $instance->update([
            'status' => 'cancellation_scheduled',
            'cancel_requested_at' => now(),
            'service_ends_at' => $this->currentPeriodEnd($instance),
        ]);

        return $this->redirectRoute('settings', navigate: true);
    }

    /**
     * End of the current monthly billing period, anchored on the subscription
     * start (the order date) rather than assuming calendar-month billing.
     */
    private function currentPeriodEnd(Instance $instance): \Illuminate\Support\Carbon
    {
        $start = $instance->order?->created_at ?? $instance->created_at ?? now();

        // Always add from the immutable start so the billing-day anchor is kept
        // (chaining addMonth would drift a Jan-31 start to Feb-28 → Mar-28).
        $months = 1;
        while ($start->copy()->addMonthsNoOverflow($months)->lessThanOrEqualTo(now())) {
            $months++;
        }

        return $start->copy()->addMonthsNoOverflow($months);
    }

    public function render()
    {
        $instance = $this->customer()?->instances()->where('status', 'active')->latest('id')->first();

        return view('livewire.confirm-cancel-package', [
            'subdomain' => $instance?->subdomain ?? '',
        ]);
    }
}
