<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Invoice;
use App\Models\Setting;
use App\Services\PdfBrowsershotService;
use App\Services\PdfService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Inertia\Inertia;
use Inertia\Response;

class InvoiceController extends Controller
{
    /**
     * Display a listing of all invoices/payments.
     */
    public function index(Request $request): Response
    {
        $query = Invoice::with(['user', 'subscription.plan']);

        // Search by invoice number, user name or email
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('invoice_number', 'like', "%{$search}%")
                    ->orWhereHas('user', function ($q) use ($search) {
                        $q->where('name', 'like', "%{$search}%")
                            ->orWhere('email', 'like', "%{$search}%");
                    });
            });
        }

        // Filter by status
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        // Filter by payment method
        if ($request->filled('payment_method')) {
            $query->where('payment_method', $request->payment_method);
        }

        // Filter by date range
        if ($request->filled('from')) {
            $query->whereDate('created_at', '>=', $request->from);
        }
        if ($request->filled('to')) {
            $query->whereDate('created_at', '<=', $request->to);
        }

        $invoices = $query->latest()->paginate(20)->withQueryString();

        // Get statistics
        $stats = [
            'total_invoices' => Invoice::count(),
            'paid_invoices' => Invoice::where('status', 'paid')->count(),
            'pending_invoices' => Invoice::where('status', 'pending')->count(),
            'overdue_invoices' => Invoice::where('status', 'pending')
                ->where('created_at', '<', now()->subDays(7))
                ->count(),
            'total_revenue' => Invoice::where('status', 'paid')->sum('total'),
            'pending_revenue' => Invoice::where('status', 'pending')->sum('total'),
            'this_month_revenue' => Invoice::where('status', 'paid')
                ->whereMonth('paid_at', now()->month)
                ->whereYear('paid_at', now()->year)
                ->sum('total'),
        ];

        return Inertia::render('Admin/Invoices/Index', [
            'invoices' => $invoices,
            'stats' => $stats,
            'filters' => $request->only(['search', 'status', 'payment_method', 'from', 'to']),
        ]);
    }

    /**
     * Display the specified invoice.
     */
    public function show(Invoice $invoice): Response
    {
        $invoice->load(['user', 'subscription.plan', 'selectedBank']);

        return Inertia::render('Admin/Invoices/Show', [
            'invoice' => $invoice,
        ]);
    }

    /**
     * Mark an invoice as paid.
     */
    public function markAsPaid(Request $request, Invoice $invoice): \Illuminate\Http\RedirectResponse
    {
        if ($invoice->isPaid()) {
            return back()->with('error', 'Esta factura ya está pagada.');
        }

        $request->validate([
            'payment_method' => 'required|in:stripe,paypal,bank_transfer,cash,wallet,other',
            'transaction_id' => 'nullable|string|max:255',
            'notes' => 'nullable|string|max:500',
        ]);

        $invoice->update([
            'status' => 'paid',
            'payment_method' => $request->payment_method,
            'transaction_id' => $request->transaction_id,
            'notes' => $request->notes,
            'paid_at' => now(),
        ]);

        // Always notify coach that invoice is paid
        $invoice->user->notify(new \App\Notifications\InvoicePaid($invoice));

        // Activate subscription if needed
        if ($invoice->subscription && in_array($invoice->subscription->status, ['pending', 'pending_payment'])) {
            $invoice->subscription->update(['status' => 'active']);

            // Notify coach of subscription activation
            $invoice->user->notify(new \App\Notifications\SubscriptionActivated($invoice->subscription));
        }

        return back()->with('success', 'Factura marcada como pagada.');
    }

    /**
     * Mark an invoice as cancelled/void.
     */
    public function cancel(Request $request, Invoice $invoice): \Illuminate\Http\RedirectResponse
    {
        if ($invoice->isPaid()) {
            return back()->with('error', 'No se puede cancelar una factura ya pagada.');
        }

        $request->validate([
            'reason' => 'nullable|string|max:500',
        ]);

        $invoice->update([
            'status' => 'cancelled',
            'notes' => $request->reason,
        ]);

        // Notify coach about cancelled invoice
        $invoice->user->notify(new \App\Notifications\InvoiceCancelled($invoice, $request->reason));

        return back()->with('success', 'Factura cancelada.');
    }

    /**
     * Download invoice PDF.
     */
    public function download(Invoice $invoice)
    {
        $invoice->load(['user', 'subscription.plan']);

        try {
            $pdfEngine = Setting::get('pdf_engine', 'browsershot');

            if ($pdfEngine === 'browsershot') {
                $filename = app(PdfBrowsershotService::class)->generateInvoice($invoice);
            } else {
                $filename = app(PdfService::class)->generateInvoice($invoice);
            }

            $filePath = storage_path("app/public/{$filename}");

            if (!file_exists($filePath)) {
                abort(404, 'No se pudo generar el PDF de la factura.');
            }

            return response()->download($filePath, "factura-{$invoice->invoice_number}.pdf");
        } catch (\Exception $e) {
            Log::error('Admin Invoice PDF Error: ' . $e->getMessage());
            // Fallback to DomPDF
            $filename = app(PdfService::class)->generateInvoice($invoice);
            $filePath = storage_path("app/public/{$filename}");
            return response()->download($filePath, "factura-{$invoice->invoice_number}.pdf");
        }
    }

    /**
     * Export invoices to CSV.
     */
    public function export(Request $request)
    {
        $query = Invoice::with(['user', 'subscription.plan']);

        // Apply same filters as index
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        if ($request->filled('from')) {
            $query->whereDate('created_at', '>=', $request->from);
        }
        if ($request->filled('to')) {
            $query->whereDate('created_at', '<=', $request->to);
        }

        $invoices = $query->latest()->get();

        $filename = 'facturas-' . now()->format('Y-m-d') . '.csv';
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => "attachment; filename=\"{$filename}\"",
        ];

        $callback = function () use ($invoices) {
            $file = fopen('php://output', 'w');

            // CSV headers
            fputcsv($file, [
                'Número',
                'Fecha',
                'Coach',
                'Email',
                'Plan',
                'Subtotal',
                'Impuesto',
                'Total',
                'Estado',
                'Método Pago',
                'ID Transacción',
                'Fecha Pago',
            ]);

            foreach ($invoices as $invoice) {
                fputcsv($file, [
                    $invoice->invoice_number,
                    $invoice->created_at->format('Y-m-d H:i'),
                    $invoice->user->name ?? 'N/A',
                    $invoice->user->email ?? 'N/A',
                    $invoice->subscription?->plan?->name ?? 'N/A',
                    number_format($invoice->subtotal, 2),
                    number_format($invoice->tax, 2),
                    number_format($invoice->total, 2),
                    $this->getStatusLabel($invoice->status),
                    $this->getPaymentMethodLabel($invoice->payment_method),
                    $invoice->transaction_id ?? '-',
                    $invoice->paid_at?->format('Y-m-d H:i') ?? '-',
                ]);
            }

            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }

    private function getStatusLabel(string $status): string
    {
        return match ($status) {
            'paid' => 'Pagada',
            'pending' => 'Pendiente',
            'cancelled' => 'Cancelada',
            'overdue' => 'Vencida',
            default => $status,
        };
    }

    private function getPaymentMethodLabel(?string $method): string
    {
        return match ($method) {
            'stripe' => 'Stripe (Tarjeta)',
            'paypal' => 'PayPal',
            'bank_transfer' => 'Transferencia Bancaria',
            'cash' => 'Efectivo',
            'wallet' => 'Billetera',
            'other' => 'Otro',
            default => $method ?? '-',
        };
    }

    /**
     * Delete multiple invoices at once.
     */
    public function bulkDelete(Request $request): \Illuminate\Http\RedirectResponse
    {
        $request->validate([
            'ids' => 'required|array|min:1',
            'ids.*' => 'exists:invoices,id',
        ]);

        $invoices = Invoice::whereIn('id', $request->ids)->get();
        $deletedCount = 0;
        $errors = [];

        foreach ($invoices as $invoice) {
            // Don't allow deleting paid invoices unless admin confirms
            if ($invoice->status === 'paid' && !$request->force) {
                $errors[] = "Factura {$invoice->invoice_number} está pagada y no puede eliminarse.";
                continue;
            }

            // Log the deletion for audit
            Log::info("Admin {$request->user()->name} deleted invoice {$invoice->invoice_number}", [
                'admin_id' => $request->user()->id,
                'invoice_id' => $invoice->id,
                'invoice_number' => $invoice->invoice_number,
                'amount' => $invoice->total,
                'status' => $invoice->status,
            ]);

            $invoice->delete();
            $deletedCount++;
        }

        if ($deletedCount === 0) {
            return back()->with('error', 'No se pudo eliminar ninguna factura. ' . implode(' ', $errors));
        }

        $message = "{$deletedCount} factura(s) eliminada(s) correctamente.";
        if (count($errors) > 0) {
            $message .= ' ' . implode(' ', $errors);
        }

        return back()->with('success', $message);
    }

    /**
     * Delete a single invoice.
     */
    public function destroy(Request $request, Invoice $invoice): \Illuminate\Http\RedirectResponse
    {
        if ($invoice->status === 'paid' && !$request->force) {
            return back()->with('error', 'No se puede eliminar una factura ya pagada.');
        }

        // Log the deletion
        Log::info("Admin {$request->user()->name} deleted invoice {$invoice->invoice_number}", [
            'admin_id' => $request->user()->id,
            'invoice_id' => $invoice->id,
        ]);

        $invoice->delete();

        return redirect()->route('admin.invoices.index')->with('success', 'Factura eliminada correctamente.');
    }
}
