<?php

namespace App\Services;

use App\Models\AuditLog;
use App\Models\Plan;
use App\Models\SaasInvoice;
use App\Models\SaasInvoiceItem;
use App\Models\SaasPayment;
use App\Models\Tenant;
use Illuminate\Support\Str;

class BillingService
{
    public function generateSubscriptionInvoice(Tenant $tenant, Plan $plan, string $billingCycle = 'monthly', float $discount = 0.0): SaasInvoice
    {
        $unitPrice = ($billingCycle === 'yearly') ? $plan->price_yearly : $plan->price_monthly;
        $subtotal = max(0, $unitPrice - $discount);
        $taxRate = 5.00; // 5% UAE VAT default
        $taxAmount = round($subtotal * ($taxRate / 100), 2);
        $total = $subtotal + $taxAmount;

        $invoiceNumber = 'INV-'.strtoupper(Str::random(4)).'-'.date('Ymd');

        $invoice = SaasInvoice::create([
            'invoice_number' => $invoiceNumber,
            'tenant_id' => $tenant->id,
            'subscription_id' => $tenant->subscription_id,
            'plan_id' => $plan->id,
            'invoice_date' => now(),
            'due_date' => now()->addDays(7),
            'subtotal' => $subtotal,
            'discount' => $discount,
            'tax_rate' => $taxRate,
            'tax_amount' => $taxAmount,
            'total' => $total,
            'paid_amount' => 0,
            'balance' => $total,
            'status' => 'issued',
            'notes' => 'Subscription fee for '.$plan->name.' ('.ucfirst($billingCycle).')',
        ]);

        SaasInvoiceItem::create([
            'invoice_id' => $invoice->id,
            'item_name' => $plan->name.' Subscription ('.ucfirst($billingCycle).')',
            'quantity' => 1,
            'unit_price' => $unitPrice,
            'total_price' => $unitPrice,
        ]);

        AuditLog::record('billing', 'invoice.generated', $invoice);

        return $invoice;
    }

    public function recordManualPayment(Tenant $tenant, ?SaasInvoice $invoice, float $amount, string $paymentMethod, ?string $reference, ?string $remarks = null): SaasPayment
    {
        $paymentNumber = 'PAY-'.strtoupper(Str::random(4)).'-'.date('Ymd');

        $payment = SaasPayment::create([
            'payment_number' => $paymentNumber,
            'tenant_id' => $tenant->id,
            'invoice_id' => $invoice?->id,
            'payment_date' => now(),
            'amount' => $amount,
            'payment_method' => $paymentMethod,
            'transaction_reference' => $reference,
            'status' => 'success',
            'remarks' => $remarks,
            'received_by' => auth()->id(),
        ]);

        if ($invoice) {
            $newPaid = $invoice->paid_amount + $amount;
            $newBalance = max(0, $invoice->total - $newPaid);
            $newStatus = ($newBalance <= 0) ? 'paid' : 'partially_paid';

            $invoice->update([
                'paid_amount' => $newPaid,
                'balance' => $newBalance,
                'status' => $newStatus,
            ]);

            // Update Tenant subscription status if invoice was overdue
            if ($tenant->status === 'payment_due' || $tenant->status === 'grace_period') {
                $tenant->update(['status' => 'active']);
            }
        }

        AuditLog::record('billing', 'payment.recorded_manual', $payment);

        return $payment;
    }
}
