<?php

namespace App\Http\Controllers;

use App\Models\Invoice;
use App\Models\Pelanggan;
use App\Models\PesanTemplate;
use App\Models\WhatsappGateway;
use App\Models\Perusahaan;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Carbon\Carbon;

class InvoiceController extends Controller
{
    /**
     * Display invoices that haven't been paid
     */
    public function belumBayar(Request $request)
    {
        // Cek dan jalankan auto billing jika diperlukan
        $this->checkAndRunAutoBilling();
        
        // Update overdue invoices first
        $this->updateOverdueInvoices();
        
        $query = Invoice::with(['pelanggan'])
            ->belumBayar();

        // Search
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('nomor_invoice', 'like', "%{$search}%")
                  ->orWhereHas('pelanggan', function($subQ) use ($search) {
                      $subQ->where('nama_lengkap', 'like', "%{$search}%")
                           ->orWhere('nomer_layanan', 'like', "%{$search}%");
                  });
            });
        }

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

        // Filter overdue only
        if ($request->boolean('overdue')) {
            $query->where('tanggal_jatuh_tempo', '<', now());
        }

        $invoices = $query->orderBy('tanggal_jatuh_tempo', 'asc')
            ->paginate(20)
            ->withQueryString();

        // Add days until due for each invoice
        $invoices->getCollection()->transform(function ($invoice) {
            $invoice->days_until_due = $invoice->days_until_due;
            return $invoice;
        });

        // Count draft invoices for info
        $draftCount = Invoice::where('status', 'draft')->count();

        return view('invoices.belum-bayar', compact('invoices', 'draftCount'));
    }

    /**
     * Display invoices that have been paid
     */
    public function sudahBayar(Request $request)
    {
        $query = Invoice::with(['pelanggan', 'createdBy', 'updatedBy'])
            ->sudahBayar()
            ->latest('tanggal_bayar');

        // Search functionality
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('nomor_invoice', 'like', "%{$search}%")
                  ->orWhereHas('pelanggan', function($q) use ($search) {
                      $q->where('nama_lengkap', 'like', "%{$search}%")
                        ->orWhere('nomer_layanan', 'like', "%{$search}%");
                  });
            });
        }

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

        // Filter by date range
        if ($request->filled('tanggal_dari')) {
            $query->whereDate('tanggal_bayar', '>=', $request->tanggal_dari);
        }

        if ($request->filled('tanggal_sampai')) {
            $query->whereDate('tanggal_bayar', '<=', $request->tanggal_sampai);
        }

        $invoices = $query->paginate(15)->withQueryString();

        return view('invoices.sudah-bayar', compact('invoices'));
    }

    /**
     * Display invoices waiting for payment confirmation
     */
    public function konfirmasi(Request $request)
    {
        $query = Invoice::with(['pelanggan', 'createdBy'])
            ->where('status', 'sent')
            ->whereNotNull('tanggal_bayar')
            ->whereNull('metode_pembayaran')
            ->latest('tanggal_bayar');

        // Search functionality
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('nomor_invoice', 'like', "%{$search}%")
                  ->orWhereHas('pelanggan', function($q) use ($search) {
                      $q->where('nama_lengkap', 'like', "%{$search}%")
                        ->orWhere('nomer_layanan', 'like', "%{$search}%");
                  });
            });
        }

        $invoices = $query->paginate(15)->withQueryString();

        return view('invoices.konfirmasi', compact('invoices'));
    }

    /**
     * Show invoice details
     */
    public function show(Invoice $invoice)
    {
        $invoice->load(['pelanggan', 'templateInvoice', 'createdBy', 'updatedBy']);
        
        return view('invoices.show', compact('invoice'));
    }

    /**
     * Update invoice data (tanggal jatuh tempo dan diskon)
     */
    public function updateInvoice(Request $request, Invoice $invoice)
    {
        try {
            // Validasi input
            $validated = $request->validate([
                'tanggal_jatuh_tempo' => 'required|date|after:today',
                'diskon' => 'nullable|numeric|min:0|max:100',
                'note' => 'nullable|string|max:500'
            ]);

            // Cek apakah invoice bisa di-edit (hanya draft, sent, overdue)
            if (!in_array($invoice->status, ['draft', 'sent', 'overdue'])) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invoice dengan status ' . $invoice->status . ' tidak dapat diedit.'
                ], 400);
            }

            // Simpan data lama untuk log
            $oldData = [
                'tanggal_jatuh_tempo' => $invoice->tanggal_jatuh_tempo->format('Y-m-d'),
                'diskon' => $invoice->diskon,
                'total_amount' => $invoice->total_amount
            ];

            // Update data
            $invoice->tanggal_jatuh_tempo = $validated['tanggal_jatuh_tempo'];
            $invoice->diskon = $validated['diskon'] ?? 0;
            $invoice->updated_by = auth()->id();

            // Hitung ulang total setelah diskon menggunakan subtotal yang sudah ada
            $subtotal = $invoice->subtotal;
            $biayaInstalasi = $invoice->biaya_instalasi ?? 0;
            
            // Hitung diskon dari subtotal (bukan biaya instalasi)
            $diskonAmount = ($subtotal * $invoice->diskon) / 100;
            $subtotalAfterDiskon = $subtotal - $diskonAmount;
            
            // Hitung PPN jika ada
            $ppnAmount = 0;
            if ($invoice->ppn_persen > 0) {
                $ppnAmount = (($subtotalAfterDiskon + $biayaInstalasi) * $invoice->ppn_persen) / 100;
            }
            
            // Total akhir
            $invoice->total_amount = $subtotalAfterDiskon + $biayaInstalasi + $ppnAmount;

            // Update status jika tanggal jatuh tempo sudah lewat
            if (now()->toDateString() > $validated['tanggal_jatuh_tempo']) {
                $invoice->status = 'overdue';
            } elseif ($invoice->status === 'overdue' && now()->toDateString() <= $validated['tanggal_jatuh_tempo']) {
                $invoice->status = 'sent';
            }

            $invoice->save();

            // Log perubahan
            Log::info('Invoice updated', [
                'invoice_id' => $invoice->id,
                'nomor_invoice' => $invoice->nomor_invoice,
                'user_id' => auth()->id(),
                'old_data' => $oldData,
                'new_data' => [
                    'tanggal_jatuh_tempo' => $invoice->tanggal_jatuh_tempo->format('Y-m-d'),
                    'diskon' => $invoice->diskon,
                    'total_amount' => $invoice->total_amount,
                    'status' => $invoice->status
                ],
                'note' => $validated['note'] ?? null
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Invoice berhasil diperbarui',
                'data' => [
                    'tanggal_jatuh_tempo' => $invoice->tanggal_jatuh_tempo->format('d/m/Y'),
                    'diskon' => $invoice->diskon,
                    'total_amount' => number_format($invoice->total_amount, 0, ',', '.'),
                    'status' => $invoice->status
                ]
            ]);

        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Data tidak valid',
                'errors' => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            Log::error('Error updating invoice', [
                'invoice_id' => $invoice->id,
                'error' => $e->getMessage(),
                'user_id' => auth()->id()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan saat memperbarui invoice: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Generate and download invoice PDF
     */
    public function download(Invoice $invoice)
    {
        try {
            $startTime = microtime(true);
            
            // Increase memory limit and max execution time for PDF generation
            ini_set('memory_limit', '512M');
            ini_set('max_execution_time', 300); // 5 minutes
            
            \Log::info('Starting download for invoice: ' . $invoice->nomor_invoice . ' at ' . date('Y-m-d H:i:s'));
            
            // Get default template or template assigned to invoice
            $template = null;
            
            if ($invoice->template_invoice_id) {
                $template = \App\Models\TemplateInvoice::find($invoice->template_invoice_id);
                \Log::info('Found assigned template: ' . ($template ? $template->nama_template : 'null'));
            }
            
            // If no template assigned, get the default template
            if (!$template) {
                $template = \App\Models\TemplateInvoice::where('is_default', true)->first();
                \Log::info('Using default template: ' . ($template ? $template->nama_template : 'null'));
            }
            
            // If still no template, get any active template
            if (!$template) {
                $template = \App\Models\TemplateInvoice::where('aktif', true)->first();
                \Log::info('Using first active template: ' . ($template ? $template->nama_template : 'null'));
            }
            
            if (!$template) {
                \Log::error('No template found for invoice: ' . $invoice->nomor_invoice);
                return response()->json(['error' => 'Template invoice tidak ditemukan!'], 404);
            }

            $htmlStartTime = microtime(true);
            \Log::info('Generating HTML content...');
            // Generate HTML using template from database
            $htmlContent = $this->generateInvoiceHtmlWithTemplate($invoice, $template);
            $htmlEndTime = microtime(true);
            \Log::info('HTML content generated, length: ' . strlen($htmlContent) . ', time: ' . round(($htmlEndTime - $htmlStartTime), 2) . 's');

            $pdfStartTime = microtime(true);
            \Log::info('Starting PDF generation...');
            // Generate PDF using DomPDF with optimized settings
            $pdf = Pdf::loadHTML($htmlContent)
                ->setOptions([
                    'defaultFont' => 'Arial',
                    'isRemoteEnabled' => false,
                    'isHtml5ParserEnabled' => true,
                    'isPhpEnabled' => false,
                    'debugKeepTemp' => false,
                    'debugPng' => false,
                    'debugCss' => false,
                    'debugLayout' => false,
                    'debugLayoutLines' => false,
                    'debugLayoutBlocks' => false,
                    'debugLayoutInline' => false,
                    'debugLayoutPaddingBox' => false,
                    'enable_remote' => false,
                    'enable_javascript' => false,
                ]);
            
            // Set paper size and orientation based on template
            $paperSize = $template->format_paper ?: 'A4';
            $orientation = $template->orientation ?: 'portrait';
            $pdf->setPaper($paperSize, $orientation);
            $pdfEndTime = microtime(true);
            \Log::info('PDF settings applied: ' . $paperSize . ' ' . $orientation . ', time: ' . round(($pdfEndTime - $pdfStartTime), 2) . 's');

            $outputStartTime = microtime(true);
            \Log::info('Generating PDF output...');
            
            // Set download headers to prevent timeout
            $filename = $invoice->nomor_invoice . '.pdf';
            
            $endTime = microtime(true);
            $totalTime = round(($endTime - $startTime), 2);
            \Log::info('PDF download completed for invoice: ' . $invoice->nomor_invoice . ', total time: ' . $totalTime . 's');
            
            return response()->streamDownload(function() use ($pdf) {
                echo $pdf->output();
            }, $filename, [
                'Content-Type' => 'application/pdf',
                'Content-Disposition' => 'attachment; filename="' . $filename . '"',
                'Cache-Control' => 'no-cache, no-store, must-revalidate',
                'Pragma' => 'no-cache',
                'Expires' => '0'
            ]);
            
        } catch (\Exception $e) {
            \Log::error('Download error for invoice ' . $invoice->nomor_invoice . ': ' . $e->getMessage());
            \Log::error('Error file: ' . $e->getFile() . ':' . $e->getLine());
            \Log::error('Stack trace: ' . $e->getTraceAsString());
            
            return response()->json([
                'error' => 'Terjadi kesalahan saat membuat PDF: ' . $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine()
            ], 500);
        }
    }

    /**
     * Mark invoice as sent
     */
    public function markAsSent(Invoice $invoice)
    {
        $invoice->update([
            'status' => 'sent',
            'updated_by' => auth()->id()
        ]);

        return redirect()->back()->with('success', 'Invoice berhasil ditandai sebagai belum lunas!');
    }

    /**
     * Confirm payment
     */
    public function confirmPayment(Request $request, Invoice $invoice)
    {
        // Check if invoice is already paid
        if ($invoice->status === 'paid') {
            return redirect()->back()->with('error', "Invoice {$invoice->nomor_invoice} sudah dalam status lunas!");
        }
        
        // Check if invoice can be marked as paid
        if (!in_array($invoice->status, ['draft', 'sent', 'overdue'])) {
            return redirect()->back()->with('error', "Invoice {$invoice->nomor_invoice} tidak dapat ditandai sebagai lunas dengan status saat ini!");
        }
        
        // Validate required fields
        $request->validate([
            'metode_pembayaran' => 'required|string|max:255',
            'admin_payment_note' => 'nullable|string|max:1000'
        ]);
        
        $metodePembayaran = $request->input('metode_pembayaran', 'CASH');
        $adminNote = $request->input('admin_payment_note', '');
        
        $invoice->markAsPaid(
            $metodePembayaran,
            $adminNote
        );

        // TAMBAHAN: Kirim WhatsApp konfirmasi ke pelanggan
        $whatsappSent = $this->sendWhatsappConfirmation($invoice);

        Log::channel('pelanggan')->info('Invoice payment confirmed', [
            'invoice_id' => $invoice->id,
            'nomor_invoice' => $invoice->nomor_invoice,
            'pelanggan' => $invoice->pelanggan->nama_lengkap,
            'amount' => $invoice->total_amount,
            'metode_pembayaran' => $metodePembayaran,
            'confirmed_by' => auth()->user()->name,
            'whatsapp_sent' => $whatsappSent
        ]);

        $successMessage = "Invoice {$invoice->nomor_invoice} berhasil ditandai sebagai lunas dengan metode pembayaran: {$metodePembayaran}!";
        
        // Tambahkan info WhatsApp ke success message
        if ($whatsappSent) {
            $successMessage .= " WhatsApp konfirmasi telah dikirim ke pelanggan.";
        } else {
            $successMessage .= " (WhatsApp konfirmasi gagal dikirim - cek log)";
        }
        
        return redirect()->back()->with('success', $successMessage);
    }

    /**
     * Reject payment confirmation
     */
    public function rejectPayment(Request $request, Invoice $invoice)
    {
        $request->validate([
            'alasan_penolakan' => 'required|string|max:1000'
        ]);

        $invoice->update([
            'status' => 'sent',
            'tanggal_bayar' => null,
            'catatan_pembayaran' => 'DITOLAK: ' . $request->alasan_penolakan,
            'updated_by' => auth()->id()
        ]);

        Log::channel('pelanggan')->info('Invoice payment rejected', [
            'invoice_id' => $invoice->id,
            'nomor_invoice' => $invoice->nomor_invoice,
            'pelanggan' => $invoice->pelanggan->nama_lengkap,
            'alasan_penolakan' => $request->alasan_penolakan,
            'rejected_by' => auth()->user()->name
        ]);

        return redirect()->back()->with('success', 'Pembayaran berhasil ditolak!');
    }

    /**
     * Cancel invoice
     */
    public function cancel(Invoice $invoice)
    {
        $invoice->update([
            'status' => 'cancelled',
            'updated_by' => auth()->id()
        ]);

        return redirect()->back()->with('success', 'Invoice berhasil dibatalkan!');
    }

    /**
     * Create invoice for customer
     */
    public function create(Request $request)
    {
        $pelangganId = $request->get('pelanggan_id');
        $pelanggan = null;
        
        if ($pelangganId) {
            $pelanggan = Pelanggan::find($pelangganId);
        }

        $pelanggans = Pelanggan::where('status', 'aktif')->get();

        return view('invoices.create', compact('pelanggan', 'pelanggans'));
    }

    /**
     * Store new invoice
     */
    public function store(Request $request)
    {
        $request->validate([
            'pelanggan_id' => 'required|exists:pelanggan,id',
            'auto_send' => 'nullable|boolean'
        ]);

        $pelanggan = Pelanggan::findOrFail($request->pelanggan_id);
        
        // Check if there's already an unpaid invoice for this customer
        $existingInvoice = Invoice::where('pelanggan_id', $pelanggan->id)
            ->belumBayar()
            ->first();

        if ($existingInvoice) {
            return redirect()->back()->with('error', 'Pelanggan masih memiliki tagihan yang belum dibayar!');
        }

        // Create invoice with autoSend option
        $autoSend = $request->has('auto_send') && $request->auto_send;
        $invoice = Invoice::createFromPelanggan($pelanggan, $autoSend);

        $statusMessage = $autoSend ? 'dan langsung ditandai sebagai terkirim' : 'dengan status draft';

        Log::channel('pelanggan')->info('Invoice created manually', [
            'invoice_id' => $invoice->id,
            'nomor_invoice' => $invoice->nomor_invoice,
            'pelanggan' => $pelanggan->nama_lengkap,
            'amount' => $invoice->total_amount,
            'status' => $invoice->status,
            'auto_send' => $autoSend,
            'created_by' => auth()->user()->name
        ]);

        return redirect()->route('invoices.show', $invoice)
            ->with('success', "Invoice berhasil dibuat {$statusMessage}!");
    }

    /**
     * Update overdue invoices
     */
    private function updateOverdueInvoices()
    {
        Invoice::where('tanggal_jatuh_tempo', '<', now())
            ->whereIn('status', ['draft', 'sent'])
            ->update([
                'status' => 'overdue',
                'updated_by' => auth()->id()
            ]);
    }

    /**
     * Bulk actions
     */
    public function bulkAction(Request $request)
    {
        $request->validate([
            'action' => 'required|in:mark_sent,mark_overdue,cancel',
            'invoice_ids' => 'required|array',
            'invoice_ids.*' => 'exists:invoices,id'
        ]);

        $invoices = Invoice::whereIn('id', $request->invoice_ids)->get();

        foreach ($invoices as $invoice) {
            switch ($request->action) {
                case 'mark_sent':
                    if ($invoice->status === 'draft') {
                        $invoice->update(['status' => 'sent', 'updated_by' => auth()->id()]);
                    }
                    break;
                case 'mark_overdue':
                    if (in_array($invoice->status, ['draft', 'sent'])) {
                        $invoice->update(['status' => 'overdue', 'updated_by' => auth()->id()]);
                    }
                    break;
                case 'cancel':
                    if ($invoice->status !== 'paid') {
                        $invoice->update(['status' => 'cancelled', 'updated_by' => auth()->id()]);
                    }
                    break;
            }
        }

        $actionLabels = [
            'mark_sent' => 'ditandai sebagai belum lunas',
            'mark_overdue' => 'ditandai sebagai terlambat',
            'cancel' => 'dibatalkan'
        ];

        return redirect()->back()->with('success', count($invoices) . ' invoice berhasil ' . $actionLabels[$request->action] . '!');
    }

    /**
     * Show bulk print form
     */
    public function showBulkPrint(Request $request)
    {
        $request->validate([
            'invoice_ids' => 'required|array',
            'invoice_ids.*' => 'exists:invoices,id'
        ]);

        $invoices = Invoice::with(['pelanggan'])->whereIn('id', $request->invoice_ids)->get();
        $templates = \App\Models\TemplateInvoice::aktif()->orderBy('nama_template')->get();

        return view('invoices.bulk-print', compact('invoices', 'templates'));
    }

    /**
     * Process bulk print
     */
    public function processBulkPrint(Request $request)
    {
        $request->validate([
            'template_id' => 'required|exists:template_invoices,id',
            'invoice_ids' => 'required|array',
            'invoice_ids.*' => 'exists:invoices,id'
        ]);

        $template = \App\Models\TemplateInvoice::findOrFail($request->template_id);
        $invoices = Invoice::with(['pelanggan'])->whereIn('id', $request->invoice_ids)->get();

        $htmlContent = '';
        foreach ($invoices as $index => $invoice) {
            $htmlContent .= $this->generateInvoiceHtmlWithTemplate($invoice, $template);
            
            // Add page break except for the last invoice
            if ($index < count($invoices) - 1) {
                $htmlContent .= '<div style="page-break-after: always;"></div>';
            }
        }

        // Return HTML for printing
        return response($htmlContent)
            ->header('Content-Type', 'text/html; charset=utf-8');
    }

    /**
     * Print invoice with template
     */
    public function printWithTemplate(Request $request, Invoice $invoice)
    {
        $request->validate([
            'template_id' => 'required|exists:template_invoices,id'
        ]);

        $template = \App\Models\TemplateInvoice::findOrFail($request->template_id);
        
        $htmlContent = $this->generateInvoiceHtmlWithTemplate($invoice, $template);

        // Return HTML for printing
        return response($htmlContent)
            ->header('Content-Type', 'text/html; charset=utf-8');
    }

    /**
     * Preview invoice with template
     */
    public function previewInvoiceWithTemplate(Invoice $invoice, \App\Models\TemplateInvoice $template)
    {
        $htmlContent = $this->generateInvoiceHtmlWithTemplate($invoice, $template);
        
        return response($htmlContent)
            ->header('Content-Type', 'text/html; charset=utf-8');
    }

    /**
     * Preview bulk template
     */
    public function previewBulkTemplate(Request $request)
    {
        $request->validate([
            'template_id' => 'required|exists:template_invoices,id',
            'invoice_ids' => 'required|array|min:1',
            'invoice_ids.*' => 'exists:invoices,id'
        ]);

        $template = \App\Models\TemplateInvoice::findOrFail($request->template_id);
        $invoices = Invoice::with(['pelanggan'])->whereIn('id', $request->invoice_ids)->get();

        if ($invoices->isEmpty()) {
            return response()->json(['error' => 'Tidak ada invoice yang dipilih'], 400);
        }

        // Preview with first invoice only
        $firstInvoice = $invoices->first();
        $htmlContent = $this->generateInvoiceHtmlWithTemplate($firstInvoice, $template);

        return response($htmlContent)
            ->header('Content-Type', 'text/html; charset=utf-8');
    }

    /**
     * Generate invoice HTML with template
     */
    private function generateInvoiceHtmlWithTemplate(Invoice $invoice, \App\Models\TemplateInvoice $template)
    {
        $pelanggan = $invoice->pelanggan;
        $layanan = $pelanggan->layanan_data;
        
        // Get company and banking data
        $perusahaan = \App\Models\Perusahaan::first();
        $banks = \App\Models\Bank::aktif()->get();
        
        // Prepare banking variables
        $bankingVars = [];
        
        // Get primary bank info (first active bank as primary)
        $primaryBank = $banks->first();
        if ($primaryBank) {
            $bankingVars['rekening_utama'] = "{$primaryBank->nama_bank} - {$primaryBank->no_rek} a.n {$primaryBank->nama_rek}";
            $bankingVars['bank_utama'] = $primaryBank->nama_bank;
            $bankingVars['nomor_rekening'] = $primaryBank->no_rek;
            $bankingVars['nama_rekening'] = $primaryBank->nama_rek;
        } else {
            $bankingVars['rekening_utama'] = '-';
            $bankingVars['bank_utama'] = '-';
            $bankingVars['nomor_rekening'] = '-';
            $bankingVars['nama_rekening'] = '-';
        }
        
        // Generate list of all active bank accounts
        $bankList = [];
        foreach ($banks as $bank) {
            $bankList[] = "{$bank->nama_bank} - {$bank->no_rek} a.n {$bank->nama_rek}";
        }
        $bankingVars['daftar_rekening'] = implode('<br>', $bankList);
        
        // Individual bank variables (up to 5 banks for more flexibility)
        for ($i = 1; $i <= 5; $i++) {
            $bank = $banks->skip($i - 1)->first();
            if ($bank) {
                $bankingVars["bank_{$i}"] = $bank->nama_bank;
                $bankingVars["rekening_{$i}"] = $bank->no_rek;
                $bankingVars["nama_rek_{$i}"] = $bank->nama_rek;
                $bankingVars["logo_bank_{$i}"] = $bank->logo_url ?? '-';
            } else {
                $bankingVars["bank_{$i}"] = '-';
                $bankingVars["rekening_{$i}"] = '-';
                $bankingVars["nama_rek_{$i}"] = '-';
                $bankingVars["logo_bank_{$i}"] = '-';
            }
        }
        
        // Bank count and status info
        $bankingVars['jumlah_bank'] = $banks->count();
        $bankingVars['bank_aktif'] = $banks->count() > 0 ? 'Ya' : 'Tidak';
        
        // Generate bank table HTML for easy integration
        $bankTableHtml = '<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; width: 100%;">';
        $bankTableHtml .= '<thead><tr style="background: #f5f5f5;"><th>Bank</th><th>No. Rekening</th><th>Atas Nama</th></tr></thead><tbody>';
        foreach ($banks as $bank) {
            $bankTableHtml .= "<tr><td>{$bank->nama_bank}</td><td>{$bank->no_rek}</td><td>{$bank->nama_rek}</td></tr>";
        }
        $bankTableHtml .= '</tbody></table>';
        $bankingVars['tabel_bank'] = $bankTableHtml;
        
        // Generate simple bank list HTML
        $bankListHtml = '<ul>';
        foreach ($banks as $bank) {
            $bankListHtml .= "<li>{$bank->nama_bank} - {$bank->no_rek} a.n {$bank->nama_rek}</li>";
        }
        $bankListHtml .= '</ul>';
        $bankingVars['list_bank'] = $bankListHtml;

        // Logo variables - handle multiple formats for flexibility
        $logoVars = [];
        if ($perusahaan && $perusahaan->logo_kantor && file_exists(public_path('storage/' . $perusahaan->logo_kantor))) {
            $logoUrl = asset('storage/' . $perusahaan->logo_kantor);
            $logoVars['logo_perusahaan'] = $logoUrl;
            $logoVars['logo_url'] = $logoUrl;
            $logoVars['logo_kantor'] = $logoUrl;
            $logoVars['logo_img_tag'] = '<img src="' . $logoUrl . '" alt="Logo Perusahaan" style="max-height: 150px;">';
            $logoVars['logo_img_small'] = '<img src="' . $logoUrl . '" alt="Logo Perusahaan" style="max-height: 100px;">';
            $logoVars['logo_img_large'] = '<img src="' . $logoUrl . '" alt="Logo Perusahaan" style="max-height: 200px;">';
            $logoVars['logo_path'] = 'storage/' . $perusahaan->logo_kantor;
            $logoVars['has_logo'] = 'Ya';
        } else {
            // Default/fallback values when no logo
            $defaultLogo = asset('images/default-logo.png');
            $logoVars['logo_perusahaan'] = $defaultLogo;
            $logoVars['logo_url'] = $defaultLogo;
            $logoVars['logo_kantor'] = $defaultLogo;
            $logoVars['logo_img_tag'] = '<img src="' . $defaultLogo . '" alt="Logo Default" style="max-height: 150px;">';
            $logoVars['logo_img_small'] = '<img src="' . $defaultLogo . '" alt="Logo Default" style="max-height: 100px;">';
            $logoVars['logo_img_large'] = '<img src="' . $defaultLogo . '" alt="Logo Default" style="max-height: 200px;">';
            $logoVars['logo_path'] = 'images/default-logo.png';
            $logoVars['has_logo'] = 'Tidak';
        }

        // Prepare all available variables
        $data = array_merge([
            // Invoice Information
            'nomor_invoice' => $invoice->nomor_invoice,
            'tanggal_invoice' => $invoice->tanggal_invoice->format('d/m/Y'),
            'tanggal_jatuh_tempo' => $invoice->tanggal_jatuh_tempo->format('d/m/Y'),
            'periode_dari' => $invoice->periode_dari->format('d/m/Y'),
            'periode_sampai' => $invoice->periode_sampai->format('d/m/Y'),
            'periode_display' => $invoice->periode_display,
            'periode_tagihan' => $invoice->periode_tagihan_label,
            'status_invoice' => $invoice->status,
            'status_invoice_label' => $invoice->status_label,
            'status_invoice_badge' => $invoice->status_badge,
            
            // Customer Information
            'nama_pelanggan' => $pelanggan->nama_lengkap,
            'nomer_layanan' => $pelanggan->nomer_layanan,
            'alamat_pelanggan' => $pelanggan->alamat_rumah,
            'nomor_hp' => $pelanggan->no_hp_whatsapp,
            'email_pelanggan' => $pelanggan->email ?: '-',
            'jenis_kelamin' => $pelanggan->jenis_kelamin_label,
            'no_ktp_sim' => $pelanggan->no_ktp_sim,
            'tanggal_daftar' => $pelanggan->tanggal_daftar->format('d/m/Y'),
            'status_pelanggan' => $pelanggan->status,
            'jenis_tagihan' => $pelanggan->jenis_tagihan,
            'koordinat_lat' => $pelanggan->koordinat_lat ?: '-',
            'koordinat_lng' => $pelanggan->koordinat_lng ?: '-',
            'ssid' => $pelanggan->ssid ?: '-',
            'password_wifi' => $pelanggan->password_wifi ?: '-',
            
            // Service Information
            'paket' => $layanan ? $layanan->nama_layanan : ($layanan ? $layanan->nama_paket : 'Layanan Tidak Ditemukan'),
            'layanan_type' => $pelanggan->layanan_type_label,
            'mode_pelanggan' => $pelanggan->mode_pelanggan,
            'kecepatan_download' => $layanan ? ($layanan->kecepatan_download ?? $layanan->bandwidth_download ?? '-') : '-',
            'kecepatan_upload' => $layanan ? ($layanan->kecepatan_upload ?? $layanan->bandwidth_upload ?? '-') : '-',
            'profile_ppp' => $pelanggan->profile_ppp ?: '-',
            'secret_ppp' => $pelanggan->secret_ppp ?: '-',
            'password_ppp' => $pelanggan->password_ppp ?: '-',
            'username_hotspot' => $pelanggan->username_hotspot ?: '-',
            'profile_hotspot' => $pelanggan->profile_hotspot ?: '-',
            'ip_address' => $pelanggan->ip_address ?: '-',
            
            // Network Information
            'coverage_area' => $pelanggan->coverageArea ? $pelanggan->coverageArea->nama_area : '-',
            'top_odp' => $pelanggan->topOdp ? $pelanggan->topOdp->nama_odp : '-',
            'port_odp' => $pelanggan->port_odp ?: '-',
            'mikrotik' => $pelanggan->mikrotik ? $pelanggan->mikrotik->nama_mikrotik : '-',
            
            // Billing Information
            'subtotal' => $invoice->subtotal_format,
            'biaya_instalasi' => $invoice->biaya_instalasi_format,
            'diskon' => $invoice->diskon_format,
            'ppn_persen' => $invoice->ppn_persen,
            'ppn_amount' => $invoice->ppn_amount_format,
            'total' => $invoice->total_amount_format,
            'total_amount' => $invoice->total_amount_format,
            'subtotal_angka' => number_format($invoice->subtotal, 0, ',', '.'),
            'biaya_instalasi_angka' => number_format($invoice->biaya_instalasi, 0, ',', '.'),
            'diskon_angka' => number_format($invoice->diskon, 0, ',', '.'),
            'ppn_amount_angka' => number_format($invoice->ppn_amount, 0, ',', '.'),
            'total_angka' => number_format($invoice->total_amount, 0, ',', '.'),
            
            // Prorate Information
            'is_prorate' => $invoice->is_prorate ? 'Ya' : 'Tidak',
            'prorate_info' => $invoice->is_prorate && $invoice->prorate_info ? json_encode($invoice->prorate_info) : '-',
            'hari_pemakaian' => $invoice->is_prorate && isset($invoice->prorate_info['hari_pemakaian']) ? $invoice->prorate_info['hari_pemakaian'] : '-',
            'total_hari' => $invoice->is_prorate && isset($invoice->prorate_info['total_hari']) ? $invoice->prorate_info['total_hari'] : '-',
            'persentase_prorate' => $invoice->is_prorate && isset($invoice->prorate_info['persentase']) ? number_format($invoice->prorate_info['persentase'], 2) . '%' : '-',
            
            // Payment Information
            'tanggal_bayar' => $invoice->tanggal_bayar ? $invoice->tanggal_bayar->format('d/m/Y H:i') : '-',
            'metode_pembayaran' => $invoice->metode_pembayaran ?: '-',
            'catatan_pembayaran' => $invoice->catatan_pembayaran ?: '-',
            'hari_sampai_jatuh_tempo' => $invoice->days_until_due,
            'is_overdue' => $invoice->is_overdue ? 'Ya' : 'Tidak',
            
            // Company Information
            'perusahaan' => $perusahaan ? $perusahaan->perusahaan : 'Nama Perusahaan',
            'nama_perusahaan' => $perusahaan ? $perusahaan->perusahaan : 'Nama Perusahaan',
            'singkatan_perusahaan' => $perusahaan ? $perusahaan->singkatan : 'Singkatan',
            'moto_perusahaan' => $perusahaan ? $perusahaan->moto : 'Moto Perusahaan',
            'owner_perusahaan' => $perusahaan ? $perusahaan->owner : 'Nama Owner',
            'wa_owner' => $perusahaan ? $perusahaan->wa_owner : 'WA Owner',
            'alamat_perusahaan' => $perusahaan ? $perusahaan->alamat_kantor : 'Alamat Perusahaan',
            'alamat_kantor' => $perusahaan ? $perusahaan->alamat_kantor : 'Alamat Kantor',
            'telepon_perusahaan' => $perusahaan ? $perusahaan->telp_kantor : 'Telepon Perusahaan',
            'telp_kantor' => $perusahaan ? $perusahaan->telp_kantor : 'Telepon Kantor',
            'email_perusahaan' => $perusahaan ? $perusahaan->email_kantor : 'Email Perusahaan',
            'email_kantor' => $perusahaan ? $perusahaan->email_kantor : 'Email Kantor',
            'website_perusahaan' => $perusahaan ? $perusahaan->web_url : 'Website Perusahaan',
            'web_url' => $perusahaan ? $perusahaan->web_url : 'Website URL',
            'ppn_berlaku' => $perusahaan ? $perusahaan->ppn_berlaku . '%' : '11%',
            'latitude_kantor' => $perusahaan ? $perusahaan->latitude : '-',
            'longitude_kantor' => $perusahaan ? $perusahaan->longitude : '-',
            'direktur' => $perusahaan ? $perusahaan->owner : 'Nama Direktur',
            'npwp' => $perusahaan ? ($perusahaan->npwp ?? '-') : 'NPWP Perusahaan',
        ], $bankingVars, $logoVars);

        // Get template content
        $header = $template->header_template ?: '';
        $body = $template->body_template;
        $footer = $template->footer_template ?: '';
        $css = $template->css_custom ?: '';

        // Combine all template parts
        $fullTemplate = $header . $body . $footer;

        // Replace variables in template - handle both normal {{var}} and HTML entity &#123;&#125;var&#125; formats
        foreach ($data as $key => $value) {
            // Replace normal format {{key}}
            $fullTemplate = str_replace('{{' . $key . '}}', $value, $fullTemplate);
            
            // Replace HTML entity format &#123;&#123;key&#125;&#125;
            $fullTemplate = str_replace('&#123;&#123;' . $key . '&#125;&#125;', $value, $fullTemplate);
        }

        // Build complete HTML
        $html = '<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Invoice - ' . $invoice->nomor_invoice . '</title>
    <style>
        @page {
            size: ' . ($template->format_paper ?: 'A4') . ' ' . ($template->orientation ?: 'portrait') . ';
            margin: 1cm;
        }
        body {
            font-family: Arial, sans-serif;
            font-size: 12px;
            line-height: 1.4;
            margin: 0;
            padding: 0;
        }
        table {
            width: 100%;
            border-collapse: collapse;
        }
        th, td {
            padding: 8px;
            text-align: left;
            border-bottom: 1px solid #ddd;
        }
        .text-center { text-align: center; }
        .text-right { text-align: right; }
        .font-bold { font-weight: bold; }
        .mb-4 { margin-bottom: 1rem; }
        .mt-4 { margin-top: 1rem; }
        @media print {
            body { print-color-adjust: exact; }
        }
        ' . $css . '
    </style>
</head>
<body>
    ' . $fullTemplate . '
</body>
</html>';

        return $html;
    }

    /**
     * Mark all draft invoices as sent
     */
    public function markAllDraftAsSent()
    {
        $draftInvoices = Invoice::where('status', 'draft')->get();
        
        if ($draftInvoices->isEmpty()) {
            return redirect()->back()->with('warning', 'Tidak ada invoice dengan status draft untuk ditandai sebagai belum lunas!');
        }
        
        $updated = 0;
        foreach ($draftInvoices as $invoice) {
            $invoice->update([
                'status' => 'sent',
                'updated_by' => auth()->id()
            ]);
            $updated++;
        }

        return redirect()->back()->with('success', "{$updated} invoice berhasil ditandai sebagai belum lunas!");
    }

    /**
     * Show auto billing settings page
     */
    public function pengaturanTagihan()
    {
        try {
            // Simple version untuk debugging
            $settings = \DB::table('auto_billing_settings')->first();
            
            // Get overdue WhatsApp settings
            $overdueSettings = \DB::table('overdue_whatsapp_settings')->first();
            
            // Get WhatsApp templates
            $whatsappTemplates = \App\Models\PesanTemplate::where('aktif', true)->get();
            
            // Get WhatsApp gateways
            $whatsappGateways = \App\Models\WhatsappGateway::where('status', 'aktif')->get();
            
            // Get recent logs dengan limit kecil
            $recentLogs = \DB::table('auto_billing_logs')
                ->orderBy('created_at', 'desc')
                ->limit(5)
                ->get();
                
            // Simplified statistics  
            $stats = [
                'total_generated_this_month' => 0, // Sementara hardcode untuk testing
                'last_execution' => $settings ? $settings->last_run : null,
                'next_execution' => null // Sementara null untuk testing
            ];

            return view('invoices.pengaturan-tagihan', compact(
                'settings', 
                'overdueSettings', 
                'whatsappTemplates', 
                'whatsappGateways', 
                'recentLogs', 
                'stats'
            ));
            
        } catch (\Exception $e) {
            // Debug mode - show error
            return response()->json([
                'error' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            ], 500);
        }
    }

    /**
     * Save auto billing settings
     */
    public function savePengaturanTagihan(Request $request)
    {
        $request->validate([
            'is_active' => 'boolean',
            'execution_date' => 'required|integer|min:1|max:31',
            'execution_time' => 'required|date_format:H:i',
        ]);

        $data = [
            'is_active' => $request->boolean('is_active'),
            'execution_date' => $request->execution_date,
            'execution_time' => $request->execution_time,
            'updated_at' => now()
        ];

        // Check if settings exist
        $existing = \DB::table('auto_billing_settings')->first();
        
        if ($existing) {
            \DB::table('auto_billing_settings')->update($data);
        } else {
            $data['created_at'] = now();
            \DB::table('auto_billing_settings')->insert($data);
        }

        $this->logAutoBilling('INFO', 'Pengaturan tagihan otomatis diperbarui', $data);

        return redirect()->route('invoices.pengaturan-tagihan')
            ->with('success', 'Pengaturan tagihan otomatis berhasil disimpan');
    }

    /**
     * Execute auto billing generation
     */
    public function executeAutoBilling()
    {
        try {
            $settings = \DB::table('auto_billing_settings')->first();
            
            if (!$settings || !$settings->is_active) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Auto billing tidak aktif'
                ]);
            }

            // Check if already run today
            if ($settings->last_run && date('Y-m-d', strtotime($settings->last_run)) == date('Y-m-d')) {
                return response()->json([
                    'status' => 'info',
                    'message' => 'Auto billing sudah dijalankan hari ini'
                ]);
            }

            $result = $this->processAutoBilling($settings);

            // Update last run
            \DB::table('auto_billing_settings')->update([
                'last_run' => now()
            ]);

            return response()->json([
                'status' => 'success',
                'message' => 'Auto billing berhasil dijalankan',
                'data' => $result
            ]);

        } catch (\Exception $e) {
            $this->logAutoBilling('ERROR', 'Error executing auto billing', ['error' => $e->getMessage()]);
            
            return response()->json([
                'status' => 'error',
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Execute auto billing manually (on-demand)
     */
    public function executeAutoBillingManual()
    {
        try {
            $this->logAutoBilling('INFO', 'Manual execution triggered by user');
            
            // Get settings
            $settings = \DB::table('auto_billing_settings')->first();
            
            if (!$settings || !$settings->is_active) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Auto billing tidak aktif. Aktifkan terlebih dahulu di pengaturan.'
                ]);
            }
            
            // Execute billing process
            $result = $this->processAutoBilling($settings, true); // true = manual execution
            
            $this->logAutoBilling('INFO', 'Manual execution completed', [
                'result' => $result,
                'executed_by' => auth()->user()->name ?? 'System'
            ]);
            
            return response()->json([
                'status' => 'success',
                'message' => 'Auto billing berhasil dijalankan secara manual!',
                'data' => [
                    'Total Pelanggan' => $result['total_pelanggan'] ?? 0,
                    'Invoice Dibuat' => $result['dibuat'] ?? 0,
                    'Sudah Ada' => $result['sudah_ada'] ?? 0,
                    'Error' => $result['error'] ?? 0,
                    'Waktu Eksekusi' => ($result['execution_time'] ?? 0) . 's',
                    'Mode' => 'Manual Execution'
                ]
            ]);
            
        } catch (\Exception $e) {
            $this->logAutoBilling('ERROR', 'Manual execution failed', [
                'error' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine()
            ]);
            
            return response()->json([
                'status' => 'error',
                'message' => 'Gagal menjalankan auto billing: ' . $e->getMessage()
            ]);
        }
    }
    
    /**
     * Execute overdue notifications manually (on-demand)
     */
    public function executeOverdueNotificationsManual()
    {
        try {
            $this->logAutoBilling('INFO', 'Manual overdue notifications triggered by user');
            
            // Execute overdue command
            $output = '';
            $exitCode = \Artisan::call('invoice:update-overdue', [], $output);
            
            // Get output content
            $commandOutput = \Artisan::output();
            
            $this->logAutoBilling('INFO', 'Manual overdue notifications completed', [
                'exit_code' => $exitCode,
                'output_length' => strlen($commandOutput),
                'executed_by' => auth()->user()->name ?? 'System'
            ]);
            
            // Parse output for statistics
            $stats = $this->parseOverdueCommandOutput($commandOutput);
            
            if ($exitCode === 0) {
                return response()->json([
                    'status' => 'success',
                    'message' => 'Overdue notifications berhasil dijalankan secara manual!',
                    'data' => array_merge($stats, [
                        'Mode' => 'Manual Execution',
                        'Exit Code' => $exitCode
                    ])
                ]);
            } else {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Command selesai dengan error (Exit Code: ' . $exitCode . ')'
                ]);
            }
            
        } catch (\Exception $e) {
            $this->logAutoBilling('ERROR', 'Manual overdue notifications failed', [
                'error' => $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine()
            ]);
            
            return response()->json([
                'status' => 'error',
                'message' => 'Gagal menjalankan overdue notifications: ' . $e->getMessage()
            ]);
        }
    }
    
    /**
     * Parse command output for statistics
     */
    private function parseOverdueCommandOutput($output)
    {
        $stats = [
            'Invoice Updated' => 0,
            'WhatsApp Sent' => 0,
            'WhatsApp Failed' => 0,
            'Services Suspended' => 0,
            'Suspend Failed' => 0
        ];
        
        // Parse output lines for statistics
        $lines = explode("\n", $output);
        foreach ($lines as $line) {
            if (preg_match('/(\d+) invoice berhasil diupdate/', $line, $matches)) {
                $stats['Invoice Updated'] = (int)$matches[1];
            }
            if (preg_match('/(\d+) WhatsApp notification berhasil/', $line, $matches)) {
                $stats['WhatsApp Sent'] = (int)$matches[1];
            }
            if (preg_match('/(\d+) WhatsApp notification gagal/', $line, $matches)) {
                $stats['WhatsApp Failed'] = (int)$matches[1];
            }
            if (preg_match('/(\d+) layanan Mikrotik berhasil disuspend/', $line, $matches)) {
                $stats['Services Suspended'] = (int)$matches[1];
            }
            if (preg_match('/(\d+) suspend Mikrotik gagal/', $line, $matches)) {
                $stats['Suspend Failed'] = (int)$matches[1];
            }
        }
        
        return $stats;
    }
    
    /**
     * View execution logs
     */
    public function viewExecutionLogs()
    {
        try {
            // Get recent auto billing logs
            $autoBillingLogs = \DB::table('auto_billing_logs')
                ->orderBy('created_at', 'desc')
                ->limit(100)
                ->get();
            
            // Get recent system logs related to auto billing and overdue
            $logPath = storage_path('logs/laravel.log');
            $systemLogs = [];
            
            if (file_exists($logPath)) {
                $logContent = file_get_contents($logPath);
                $logLines = explode("\n", $logContent);
                
                // Filter relevant logs
                $relevantLogs = array_filter($logLines, function($line) {
                    return strpos($line, 'Auto billing') !== false || 
                           strpos($line, 'overdue') !== false ||
                           strpos($line, 'UpdateOverdueInvoices') !== false ||
                           strpos($line, 'suspended due to overdue') !== false;
                });
                
                $systemLogs = array_slice(array_reverse($relevantLogs), 0, 50);
            }
            
            return view('invoices.execution-logs', [
                'autoBillingLogs' => $autoBillingLogs,
                'systemLogs' => $systemLogs
            ]);
            
        } catch (\Exception $e) {
            return back()->with('error', 'Gagal memuat logs: ' . $e->getMessage());
        }
    }

    /**
     * Process auto billing generation
     */
    private function processAutoBilling($settings, $isManual = false)
    {
        $startTime = microtime(true);
        
        $this->logAutoBilling('INFO', 'Memulai proses auto billing' . ($isManual ? ' (manual)' : ''));

        // Get all active customers
        $pelangganAktif = Pelanggan::where('status', 'aktif')->get();
        $totalPelanggan = $pelangganAktif->count();
        
        $bulanTarget = 'bulanan'; // Use same format as existing data
        $tanggalInvoice = date('Y-m-01');
        
        $jumlahDibuat = 0;
        $jumlahSudahAda = 0;
        $jumlahError = 0;
        $errors = [];

        foreach ($pelangganAktif as $pelanggan) {
            try {
                // Check if invoice already exists for this month
                $existingInvoice = Invoice::where('pelanggan_id', $pelanggan->id)
                    ->where('periode_tagihan', $bulanTarget)
                    ->first();

                if ($existingInvoice) {
                    $jumlahSudahAda++;
                    continue;
                }

                // Calculate amounts
                $biayaBulanan = $pelanggan->biaya_bulanan ?? 0;
                $ppnRate = $pelanggan->ppn_persen ?? 0;
                $ppnAmount = $ppnRate > 0 ? ($biayaBulanan * $ppnRate / 100) : 0;
                $totalTagihan = $biayaBulanan + $ppnAmount;

                // Calculate due date
                $jatuhTempo = $pelanggan->jatuh_tempo ?? 7;
                $tanggalJatuhTempo = date('Y-m-d', strtotime($tanggalInvoice . ' +' . $jatuhTempo . ' days'));

                // Calculate periode billing
                $periodeDari = date('Y-m-01'); // First day of current month
                $periodeSampai = date('Y-m-t'); // Last day of current month

                // Generate invoice number
                $nomorInvoice = $this->generateNomorInvoice();

                // Create invoice
                $invoice = Invoice::create([
                    'nomor_invoice' => $nomorInvoice,
                    'pelanggan_id' => $pelanggan->id,
                    'periode_tagihan' => $bulanTarget,
                    'periode_dari' => $periodeDari,
                    'periode_sampai' => $periodeSampai,
                    'tanggal_invoice' => $tanggalInvoice,
                    'tanggal_jatuh_tempo' => $tanggalJatuhTempo,
                    'subtotal' => $biayaBulanan,
                    'ppn_persen' => $ppnRate,
                    'ppn_amount' => $ppnAmount,
                    'total_amount' => $totalTagihan,
                    'status' => 'draft',
                    'created_by' => auth()->id() ?? 1,
                ]);

                if ($invoice) {
                    $jumlahDibuat++;
                } else {
                    $jumlahError++;
                    $errors[] = "Gagal membuat invoice untuk {$pelanggan->nama_lengkap}";
                }

            } catch (\Exception $e) {
                $jumlahError++;
                $error = "Error processing {$pelanggan->nama_lengkap}: " . $e->getMessage();
                $errors[] = $error;
                $this->logAutoBilling('ERROR', $error);
            }
        }

        $result = [
            'total_pelanggan' => $totalPelanggan,
            'dibuat' => $jumlahDibuat,
            'sudah_ada' => $jumlahSudahAda,
            'error' => $jumlahError,
            'errors' => $errors,
            'execution_time' => round(microtime(true) - $startTime, 2),
            'is_manual' => $isManual
        ];

        $this->logAutoBilling('INFO', 'Auto billing selesai', $result);

        return $result;
    }

    /**
     * Check if it's time to execute auto billing
     */
    public function checkAutoBillingTime()
    {
        $settings = \DB::table('auto_billing_settings')->first();
        
        if (!$settings || !$settings->is_active) {
            return response()->json(['should_execute' => false, 'reason' => 'Auto billing tidak aktif']);
        }

        $currentDate = date('j'); // Day of month without leading zeros
        $currentTime = date('H:i');
        $targetDate = $settings->execution_date;
        $targetTime = $settings->execution_time;

        // Check if it's the right date
        if ($currentDate != $targetDate) {
            return response()->json([
                'should_execute' => false, 
                'reason' => "Belum tanggal eksekusi. Target: tanggal {$targetDate}, sekarang: tanggal {$currentDate}"
            ]);
        }

        // Check if it's the right time (with 5 minute tolerance)
        $currentTimeInMinutes = (int)date('H') * 60 + (int)date('i');
        $targetTimeInMinutes = (int)substr($targetTime, 0, 2) * 60 + (int)substr($targetTime, 3, 2);
        $timeDifference = abs($currentTimeInMinutes - $targetTimeInMinutes);

        if ($timeDifference > 5) { // 5 minute tolerance
            return response()->json([
                'should_execute' => false,
                'reason' => "Belum waktunya eksekusi. Target: {$targetTime}, sekarang: {$currentTime}"
            ]);
        }

        // Check if already executed today
        if ($settings->last_run && date('Y-m-d', strtotime($settings->last_run)) == date('Y-m-d')) {
            return response()->json([
                'should_execute' => false,
                'reason' => 'Sudah dijalankan hari ini pada: ' . date('d/m/Y H:i', strtotime($settings->last_run))
            ]);
        }

        return response()->json(['should_execute' => true]);
    }

    /**
     * Generate unique invoice number
     */
    private function generateNomorInvoice()
    {
        $prefix = 'INV';
        $date = date('Ymd');
        
        // Get last invoice number for today
        $lastInvoice = Invoice::where('nomor_invoice', 'like', "{$prefix}-{$date}-%")
            ->orderBy('nomor_invoice', 'desc')
            ->first();

        if ($lastInvoice) {
            $lastNumber = (int)substr($lastInvoice->nomor_invoice, -4);
            $newNumber = str_pad($lastNumber + 1, 4, '0', STR_PAD_LEFT);
        } else {
            $newNumber = '0001';
        }

        return "{$prefix}-{$date}-{$newNumber}";
    }

    /**
     * Log auto billing activity
     */
    private function logAutoBilling($level, $message, $context = [])
    {
        \DB::table('auto_billing_logs')->insert([
            'level' => $level,
            'message' => $message,
            'context' => json_encode($context),
            'created_at' => now()
        ]);

        Log::info("[Auto Billing] {$message}", $context);
    }

    /**
     * Get next execution time
     */
    private function getNextExecutionTime($settings)
    {
        if (!$settings) return null;

        $targetDate = $settings->execution_date;
        $targetTime = $settings->execution_time;
        
        $currentDate = date('j');
        $currentMonth = date('Y-m');
        
        if ($currentDate <= $targetDate) {
            // This month
            return date('Y-m-' . str_pad($targetDate, 2, '0', STR_PAD_LEFT) . ' ' . $targetTime . ':00');
        } else {
            // Next month
            $nextMonth = date('Y-m', strtotime('+1 month'));
            return $nextMonth . '-' . str_pad($targetDate, 2, '0', STR_PAD_LEFT) . ' ' . $targetTime . ':00';
        }
    }

    /**
     * Mark invoice as paid directly by admin (without payment confirmation)
     */
    public function markAsPaidDirectly(Request $request, Invoice $invoice)
    {
        // Check if invoice is already paid
        if ($invoice->status === 'paid') {
            return redirect()->back()->with('error', "Invoice {$invoice->nomor_invoice} sudah dalam status lunas!");
        }
        
        // Check if invoice can be marked as paid
        if (!in_array($invoice->status, ['draft', 'sent', 'overdue'])) {
            return redirect()->back()->with('error', "Invoice {$invoice->nomor_invoice} tidak dapat ditandai sebagai lunas dengan status saat ini!");
        }
        
        $adminNote = $request->input('admin_payment_note', '');
        $metodePembayaran = $request->input('metode_pembayaran', 'CASH');
        $paymentNote = 'Dibayar langsung oleh admin: ' . auth()->user()->name;
        
        if (!empty($adminNote)) {
            $paymentNote .= ' | Catatan: ' . $adminNote;
        }
        
        $invoice->markAsPaid(
            $metodePembayaran, // Use selected payment method
            $paymentNote
        );

        // Send WhatsApp confirmation to customer
        $whatsappSent = $this->sendWhatsappConfirmation($invoice);

        // Auto-enable PPP secret if customer was isolated
        $enableResult = $this->enableMikrotikService($invoice->pelanggan);
        
        Log::channel('pelanggan')->info('Invoice marked as paid directly by admin', [
            'invoice_id' => $invoice->id,
            'nomor_invoice' => $invoice->nomor_invoice,
            'pelanggan' => $invoice->pelanggan->nama_lengkap,
            'amount' => $invoice->total_amount,
            'admin' => auth()->user()->name,
            'payment_method' => $metodePembayaran,
            'admin_note' => $adminNote,
            'whatsapp_sent' => $whatsappSent,
            'ppp_enable_success' => $enableResult['success']
        ]);

        $successMessage = "Invoice {$invoice->nomor_invoice} berhasil ditandai sebagai lunas dengan metode pembayaran: {$metodePembayaran}!";
        
        // Add PPP enable status to success message
        if ($enableResult['success']) {
            $successMessage .= " Layanan PPP telah diaktifkan kembali.";
        } else {
            $successMessage .= " ⚠️ Peringatan: Gagal mengaktifkan PPP secret (" . $enableResult['message'] . ").";
        }
        
        if ($whatsappSent) {
            return redirect()->back()
                ->with('success', $successMessage)
                ->with('whatsapp_success', "✅ WhatsApp konfirmasi berhasil dikirim ke {$invoice->pelanggan->nama_lengkap} ({$invoice->pelanggan->no_hp_whatsapp})");
        } else {
            return redirect()->back()
                ->with('success', $successMessage)
                ->with('whatsapp_error', "⚠️ WhatsApp konfirmasi GAGAL dikirim ke {$invoice->pelanggan->nama_lengkap}. Silakan cek log atau kirim manual.");
        }
    }

    /**
     * Send WhatsApp confirmation after payment marked as paid
     */
    private function sendWhatsappConfirmation(Invoice $invoice)
    {
        try {
            Log::channel('pelanggan')->info('Memulai pengiriman WhatsApp konfirmasi pembayaran untuk invoice: ' . $invoice->nomor_invoice);

            // Get active WhatsApp gateway
            $whatsappGateway = WhatsappGateway::where('status', 'aktif')->first();
            if (!$whatsappGateway) {
                Log::channel('pelanggan')->warning('Tidak ada WhatsApp Gateway yang aktif');
                return false;
            }

            // Get payment confirmation template
            $template = PesanTemplate::where('slug', 'konfirmasi-pembayaran-lunas')->where('aktif', true)->first();
            if (!$template) {
                Log::channel('pelanggan')->warning('Template pesan "konfirmasi-pembayaran-lunas" tidak ditemukan atau tidak aktif');
                return false;
            }

            // Get company data
            $perusahaan = \App\Models\Perusahaan::first();
            $namaPerusahaan = $perusahaan ? $perusahaan->perusahaan : 'ISP Provider';

            // Prepare template variables
            $variables = [
                'nama_pelanggan' => $invoice->pelanggan->nama_lengkap,
                'nomor_invoice' => $invoice->nomor_invoice,
                'total_tagihan' => $invoice->total_amount_format,
                'metode_pembayaran' => $invoice->metode_pembayaran,
                'tanggal_bayar' => $invoice->tanggal_bayar->format('d/m/Y H:i'),
                'periode_tagihan' => $invoice->periode_tagihan_label ?? $invoice->periode_display,
                'nama_perusahaan' => $namaPerusahaan
            ];

            // Replace template variables
            $message = $this->replaceTemplateVariables($template->kont_template, $variables);

            // Send WhatsApp to customer
            $customerPhone = $invoice->pelanggan->no_hp_whatsapp;
            if (!$customerPhone) {
                Log::channel('pelanggan')->warning('Pelanggan tidak memiliki nomor WhatsApp: ' . $invoice->pelanggan->nama_lengkap);
                return false;
            }

            $result = $this->sendWhatsapp($whatsappGateway, $customerPhone, $message);
            
            if ($result) {
                Log::channel('pelanggan')->info('WhatsApp konfirmasi pembayaran berhasil dikirim ke: ' . $customerPhone . ' untuk invoice: ' . $invoice->nomor_invoice);
                return true;
            } else {
                Log::channel('pelanggan')->error('Gagal mengirim WhatsApp konfirmasi pembayaran ke: ' . $customerPhone . ' untuk invoice: ' . $invoice->nomor_invoice);
                return false;
            }

        } catch (\Exception $e) {
            Log::channel('pelanggan')->error('Error saat mengirim WhatsApp konfirmasi pembayaran: ' . $e->getMessage(), [
                'invoice_id' => $invoice->id,
                'nomor_invoice' => $invoice->nomor_invoice,
                'exception' => $e
            ]);
            return false;
        }
    }

    /**
     * Send WhatsApp message
     */
    private function sendWhatsapp($gateway, $number, $message)
    {
        try {
            $url = $gateway->base_url . $gateway->endpoint;
            
            $params = [
                'api_key' => $gateway->api_key,
                'sender' => $gateway->sender_number,
                'number' => $this->formatPhoneNumber($number),
                'message' => $message
            ];

            if ($gateway->method === 'POST') {
                $response = Http::timeout($gateway->timeout)->post($url, $params);
            } else {
                $response = Http::timeout($gateway->timeout)->get($url, $params);
            }

            if ($response->successful()) {
                Log::channel('pelanggan')->info('WhatsApp berhasil dikirim ke: ' . $number, [
                    'response_status' => $response->status(),
                    'response_body' => $response->body()
                ]);
                return true;
            } else {
                Log::channel('pelanggan')->error('WhatsApp gagal dikirim ke: ' . $number, [
                    'response_status' => $response->status(),
                    'response_body' => $response->body()
                ]);
                return false;
            }
        } catch (\Exception $e) {
            Log::channel('pelanggan')->error('Exception saat mengirim WhatsApp ke: ' . $number, [
                'error' => $e->getMessage(),
                'exception' => $e
            ]);
            return false;
        }
    }

    /**
     * Replace template variables
     */
    private function replaceTemplateVariables($template, $variables)
    {
        foreach ($variables as $key => $value) {
            $template = str_replace('{{' . $key . '}}', $value, $template);
        }
        return $template;
    }

    /**
     * Format phone number to international format
     */
    private function formatPhoneNumber($number)
    {
        // Remove non-numeric characters
        $number = preg_replace('/[^0-9]/', '', $number);
        
        // Convert to international format
        if (substr($number, 0, 1) === '0') {
            $number = '62' . substr($number, 1);
        } elseif (substr($number, 0, 2) !== '62') {
            $number = '62' . $number;
        }
        
        return $number;
    }

    /**
     * Kirim invoice ke pelanggan via WhatsApp
     */
    public function sendToCustomer(Request $request, Invoice $invoice)
    {
        try {
            // Debug log
            Log::info('sendToCustomer called', [
                'invoice_id' => $invoice->id,
                'invoice_status' => $invoice->status,
                'pelanggan_id' => $invoice->pelanggan->id,
                'no_hp_whatsapp' => $invoice->pelanggan->no_hp_whatsapp ?? 'kosong',
                'request_data' => $request->all()
            ]);

            // Validasi status invoice
            if ($invoice->status === 'draft') {
                return response()->json([
                    'success' => false,
                    'message' => 'Invoice dengan status draft tidak dapat dikirim.'
                ], 400);
            }

            // Validasi nomor WhatsApp pelanggan
            if (empty($invoice->pelanggan->no_hp_whatsapp)) {
                Log::warning('Pelanggan tidak memiliki nomor WhatsApp', [
                    'invoice_id' => $invoice->id,
                    'pelanggan_id' => $invoice->pelanggan->id,
                    'pelanggan_nama' => $invoice->pelanggan->nama_lengkap
                ]);
                
                return response()->json([
                    'success' => false,
                    'message' => 'Pelanggan "' . $invoice->pelanggan->nama_lengkap . '" tidak memiliki nomor WhatsApp. Silakan update data pelanggan terlebih dahulu.'
                ], 400);
            }

            // Update status menjadi 'sent' jika masih draft
            if ($invoice->status === 'draft') {
                $invoice->update(['status' => 'sent']);
            }

            // Log aktivitas
            Log::info('Mengirim invoice ke pelanggan', [
                'invoice_id' => $invoice->id,
                'nomor_invoice' => $invoice->nomor_invoice,
                'pelanggan' => $invoice->pelanggan->nama_lengkap,
                'no_wa' => $invoice->pelanggan->no_wa,
                'admin' => auth()->user()->name
            ]);

            // Kirim WhatsApp
            $whatsappSent = $this->sendInvoiceWhatsapp($invoice, $request->catatan);

            return response()->json([
                'success' => true,
                'message' => 'Invoice berhasil dikirim ke pelanggan!',
                'whatsapp_sent' => $whatsappSent['success'],
                'whatsapp_error' => $whatsappSent['error'] ?? null
            ]);

        } catch (\Exception $e) {
            Log::error('Error sending invoice to customer', [
                'invoice_id' => $invoice->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan saat mengirim invoice: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Send WhatsApp untuk pengiriman invoice
     */
    private function sendInvoiceWhatsapp(Invoice $invoice, $catatan = null)
    {
        try {
            // Ambil template pengiriman invoice
            $template = PesanTemplate::where('slug', 'pengiriman-invoice')
                                   ->where('aktif', true)
                                   ->first();

            if (!$template) {
                Log::warning('Template pengiriman invoice tidak ditemukan');
                return ['success' => false, 'error' => 'Template pesan tidak ditemukan'];
            }

            // Ambil gateway WhatsApp aktif
            $gateway = WhatsappGateway::where('status', 'aktif')->first();
            
            if (!$gateway) {
                Log::warning('WhatsApp gateway tidak ditemukan atau tidak aktif');
                return ['success' => false, 'error' => 'Gateway WhatsApp tidak tersedia'];
            }

            // Get company data
            $perusahaan = \App\Models\Perusahaan::first();
            $namaPerusahaan = $perusahaan ? $perusahaan->perusahaan : 'ISP Provider';

            // Siapkan variables untuk template
            $variables = [
                'nama_pelanggan' => $invoice->pelanggan->nama_lengkap,
                'nomor_invoice' => $invoice->nomor_invoice,
                'periode_tagihan' => $invoice->periode_tagihan_label,
                'total_tagihan' => $invoice->total_amount_format,
                'tanggal_jatuh_tempo' => \Carbon\Carbon::parse($invoice->due_date)->format('d/m/Y'),
                'nama_perusahaan' => $namaPerusahaan
            ];

            // Replace template variables
            $message = $this->replaceTemplateVariables($template->kont_template, $variables);
            
            // Tambahkan catatan jika ada
            if (!empty($catatan)) {
                $message .= "\n\nCatatan: " . $catatan;
            }

            // Format nomor HP
            $phoneNumber = $this->formatPhoneNumber($invoice->pelanggan->no_hp_whatsapp);

            // Kirim WhatsApp
            $result = $this->sendWhatsapp($gateway, $phoneNumber, $message);

            // Log hasil
            Log::info('WhatsApp invoice terkirim', [
                'invoice_id' => $invoice->id,
                'nomor_invoice' => $invoice->nomor_invoice,
                'pelanggan' => $invoice->pelanggan->nama_lengkap,
                'phone' => $phoneNumber,
                'success' => $result,
                'message_sent' => $message
            ]);

            return ['success' => $result, 'error' => $result ? null : 'Gagal mengirim WhatsApp'];

        } catch (\Exception $e) {
            Log::error('Error sending WhatsApp invoice', [
                'invoice_id' => $invoice->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    /**
     * Save overdue WhatsApp settings
     */
    public function saveOverdueWhatsappSettings(Request $request)
    {
        $request->validate([
            'is_active' => 'boolean',
            'template_slug' => 'required|string',
            'whatsapp_gateway_id' => 'required|integer',
            'execution_time' => 'required|date_format:H:i',
            'grace_days' => 'integer|min:0|max:7',
            'send_daily' => 'boolean',
            'stop_on_payment' => 'boolean',
            'notification_days' => 'nullable|string',
            'auto_suspend_enabled' => 'boolean',
            'suspend_mode' => 'required|in:pppoe_only,hotspot_only,all',
            'update_pelanggan_status' => 'boolean'
        ]);

        // Process notification days
        $notificationDays = null;
        if ($request->notification_days) {
            $days = array_map('trim', explode(',', $request->notification_days));
            $days = array_filter($days, 'is_numeric');
            $notificationDays = json_encode(array_map('intval', $days));
        }

        $data = [
            'is_active' => $request->boolean('is_active'),
            'template_slug' => $request->template_slug,
            'whatsapp_gateway_id' => $request->whatsapp_gateway_id,
            'execution_time' => $request->execution_time,
            'grace_days' => $request->grace_days ?? 0,
            'send_daily' => $request->boolean('send_daily'),
            'stop_on_payment' => $request->boolean('stop_on_payment'),
            'notification_days' => $notificationDays,
            'auto_suspend_enabled' => $request->boolean('auto_suspend_enabled'),
            'suspend_mode' => $request->suspend_mode,
            'update_pelanggan_status' => $request->boolean('update_pelanggan_status'),
            'updated_at' => now()
        ];

        // Check if settings exist
        $existing = \DB::table('overdue_whatsapp_settings')->first();
        
        if ($existing) {
            \DB::table('overdue_whatsapp_settings')->update($data);
        } else {
            $data['created_at'] = now();
            \DB::table('overdue_whatsapp_settings')->insert($data);
        }

        $this->logAutoBilling('INFO', 'Pengaturan overdue WhatsApp dan auto-suspend diperbarui', $data);

        return redirect()->route('invoices.pengaturan-tagihan')
            ->with('success', 'Pengaturan Auto WhatsApp Overdue dan Auto-Suspend berhasil disimpan');
    }

    /**
     * Simpan pengaturan invoice settings yang baru
     */
    public function saveInvoiceSettings(Request $request)
    {
        try {
            $settings = \App\Models\AutoBillingSettings::firstOrCreate([]);
            
            $settings->update([
                'enabled' => $request->boolean('enabled'),
                'execution_time' => $request->input('execution_time', '01:00'),
                'execution_day' => $request->input('execution_day', 1),
                'whatsapp_gateway_id' => $request->input('whatsapp_gateway_id'),
                'send_whatsapp' => $request->boolean('send_whatsapp'),
                'days_before_due' => $request->input('days_before_due', 3)
            ]);

            return redirect()->route('invoices.settings')
                ->with('success', 'Pengaturan berhasil disimpan');

        } catch (\Exception $e) {
            return redirect()->back()
                ->with('error', 'Gagal menyimpan pengaturan: ' . $e->getMessage());
        }
    }

    /**
     * Eksekusi auto billing versi baru
     */
    public function executeAutoBillingNew()
    {
        try {
            $settings = \App\Models\AutoBillingSettings::first();
            
            if (!$settings || !$settings->enabled) {
                return response()->json([
                    'success' => false,
                    'message' => 'Auto billing tidak diaktifkan'
                ]);
            }

            $result = $this->processAutoBilling($settings, true);

            return response()->json([
                'success' => true,
                'message' => 'Auto billing berhasil dijalankan',
                'data' => $result
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Simpan pengaturan notifikasi overdue
     */
    public function saveOverdueSettings(Request $request)
    {
        try {
            $validated = $request->validate([
                'overdue_enabled' => 'boolean',
                'overdue_days' => 'integer|min:1|max:365',
                'overdue_notification_enabled' => 'boolean',
                'overdue_isolation_enabled' => 'boolean',
                'overdue_notification_frequency' => 'in:once,daily,weekly',
                'overdue_isolation_delay' => 'integer|min:0|max:365'
            ]);

            foreach ($validated as $key => $value) {
                DB::table('pengaturan_tagihan')->updateOrInsert(
                    ['key' => $key],
                    ['value' => $value, 'updated_at' => now()]
                );
            }

            return response()->json([
                'success' => true,
                'message' => 'Pengaturan berhasil disimpan!'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Cek dan jalankan auto billing jika sudah waktunya
     */
    private function checkAndRunAutoBilling()
    {
        try {
            // Ambil settings auto billing
            $settings = \App\Models\AutoBillingSetting::getActiveSettings();
            
            // Ambil tanggal sekarang
            $today = now();
            $currentDate = $today->format("Y-m-d");
            $currentMonth = $today->format("Y-m");
            
            // Cek apakah sudah pernah generate invoice bulan ini
            $lastGenerated = \Cache::get("auto_billing_last_run", null);
            
            // Tentukan apakah hari ini adalah hari generate
            $isGenerationDay = $this->isGenerationDay($settings);
            
            // Jika belum pernah generate bulan ini dan hari ini adalah hari generate
            if ($isGenerationDay && (!$lastGenerated || $lastGenerated < $currentMonth . "-01")) {
                
                $this->executeAutoBillingInternal($settings);
                
                // Simpan tanggal terakhir generate
                \Cache::put("auto_billing_last_run", $currentDate, now()->addMonths(2));
                
                // Log auto billing
                \Log::info("Auto billing executed automatically", [
                    "executed_at" => $currentDate,
                    "triggered_by" => "page_access",
                    "settings" => [
                        "generate_day" => $settings->generate_day,
                        "due_date_mode" => $settings->due_date_mode,
                        "advance_generate" => $settings->advance_generate
                    ]
                ]);
            }
        } catch (\Exception $e) {
            \Log::error("Error in auto billing check", [
                "error" => $e->getMessage(),
                "trace" => $e->getTraceAsString()
            ]);
        }
    }
    
    /**
     * Check apakah hari ini adalah hari generate berdasarkan settings
     */
    private function isGenerationDay($settings)
    {
        $today = now();
        
        if ($settings->advance_generate) {
            // Generate beberapa hari sebelum bulan baru
            $targetDate = $today->copy()->addMonth()->startOfMonth()->subDays($settings->advance_days);
            return $today->day == $targetDate->day && $today->month == $targetDate->month;
        } else {
            // Generate pada tanggal tertentu di bulan ini
            return $today->day >= $settings->generate_day;
        }
    }
    
    /**
     * Execute auto billing internal dengan settings
     */
    private function executeAutoBillingInternal($settings = null)
    {
        try {
            // Ambil settings jika tidak diberikan
            if (!$settings) {
                $settings = \App\Models\AutoBillingSetting::getActiveSettings();
            }
            
            // Ambil semua pelanggan aktif
            $pelanggan = \App\Models\Pelanggan::where("status", "aktif")->get();
            
            $generated = 0;
            $errors = 0;
            $generateDate = now();
            
            foreach ($pelanggan as $customer) {
                try {
                    // Cek apakah sudah ada invoice bulan ini
                    $existingInvoice = \App\Models\Invoice::where("pelanggan_id", $customer->id)
                        ->where("tanggal_invoice", ">=", now()->startOfMonth())
                        ->where("tanggal_invoice", "<=", now()->endOfMonth())
                        ->first();
                    
                    if ($existingInvoice) {
                        continue; // Skip jika sudah ada invoice bulan ini
                    }
                    
                    // Calculate due date berdasarkan settings dan customer
                    $dueDate = $settings->calculateDueDate($customer, $generateDate);
                    
                    // Generate invoice baru
                    $invoice = new \App\Models\Invoice();
                    $invoice->pelanggan_id = $customer->id;
                    $invoice->nomor_invoice = $this->generateNomorInvoice();
                    $invoice->tanggal_invoice = $generateDate->format('Y-m-d');
                    $invoice->tanggal_jatuh_tempo = $dueDate->format('Y-m-d');
                    $invoice->periode_tagihan = 'bulanan';
                    $invoice->periode_dari = now()->startOfMonth()->format('Y-m-d');
                    $invoice->periode_sampai = now()->endOfMonth()->format('Y-m-d');
                    $invoice->subtotal = $customer->layanan_data ? $customer->layanan_data->harga : 0;
                    $invoice->total_amount = $invoice->subtotal;
                    $invoice->status = "draft";
                    $invoice->created_by = 1; // System user
                    $invoice->save();
                    
                    $generated++;
                    
                    // Log detail per customer
                    \Log::info("Invoice generated for customer", [
                        "customer_id" => $customer->id,
                        "customer_name" => $customer->nama_lengkap,
                        "due_date_setting" => $customer->due_date_day,
                        "calculated_due_date" => $dueDate->format("Y-m-d"),
                        "invoice_number" => $invoice->nomor_invoice,
                        "due_date_mode" => $settings->due_date_mode
                    ]);
                    
                } catch (\Exception $e) {
                    $errors++;
                    \Log::error("Error generating invoice for customer", [
                        "customer_id" => $customer->id,
                        "customer_name" => $customer->nama_lengkap,
                        "error" => $e->getMessage()
                    ]);
                }
            }
            
            // Log hasil
            \Log::info("Auto billing completed", [
                "total_customers" => $pelanggan->count(),
                "invoices_generated" => $generated,
                "errors" => $errors,
                "executed_at" => $generateDate->format("Y-m-d H:i:s"),
                "settings_used" => [
                    "generate_day" => $settings->generate_day,
                    "due_date_mode" => $settings->due_date_mode,
                    "default_due_days" => $settings->default_due_days
                ]
            ]);
            
        } catch (\Exception $e) {
            \Log::error("Error in executeAutoBillingInternal", [
                "error" => $e->getMessage(),
                "trace" => $e->getTraceAsString()
            ]);
        }
    }

    /**
     * Isolir pelanggan karena tunggakan pembayaran
     */
    public function isolirPelanggan(Request $request, \App\Models\Pelanggan $pelanggan)
    {
        try {
            // Validasi request
            $request->validate([
                'nomor_invoice' => 'required|string'
            ]);

            $nomorInvoice = $request->input('nomor_invoice');

            // Log aktivitas isolir
            Log::channel('pelanggan')->info('Memulai proses isolir pelanggan', [
                'pelanggan_id' => $pelanggan->id,
                'nama_pelanggan' => $pelanggan->nama_lengkap,
                'nomer_layanan' => $pelanggan->nomer_layanan,
                'nomor_invoice' => $nomorInvoice,
                'admin' => auth()->user()->name
            ]);

            // 1. Kirim WhatsApp notifikasi isolir
            $whatsappResult = $this->sendIsolirWhatsapp($pelanggan, $nomorInvoice);

            // 2. Isolir layanan di Mikrotik
            $mikrotikResult = $this->isolirMikrotikService($pelanggan);

            // Tentukan hasil akhir
            $success = $whatsappResult['success'] && $mikrotikResult['success'];

            // Log hasil akhir
            Log::channel('pelanggan')->info('Proses isolir pelanggan selesai', [
                'pelanggan_id' => $pelanggan->id,
                'nama_pelanggan' => $pelanggan->nama_lengkap,
                'whatsapp_success' => $whatsappResult['success'],
                'mikrotik_success' => $mikrotikResult['success'],
                'overall_success' => $success
            ]);

            if ($success) {
                // 3. Update status invoice menjadi 'overdue' setelah isolir berhasil
                $invoice = \App\Models\Invoice::where('pelanggan_id', $pelanggan->id)
                                            ->where('nomor_invoice', $nomorInvoice)
                                            ->first();

                if ($invoice) {
                    $invoice->update(['status' => 'overdue']);
                    Log::info('Status invoice berhasil diupdate menjadi overdue', [
                        'invoice_id' => $invoice->id,
                        'nomor_invoice' => $nomorInvoice,
                        'old_status' => $invoice->getOriginal('status'),
                        'new_status' => 'overdue'
                    ]);
                }

                return redirect()->back()->with('success', 'Pelanggan berhasil diisolir dan WhatsApp notifikasi terkirim!');
            } else {
                return redirect()->back()->with('error', 'Terjadi kesalahan saat proses isolir pelanggan. Silakan cek log.');
            }

        } catch (\Exception $e) {
            Log::error('Error pada proses isolir pelanggan', [
                'pelanggan_id' => $pelanggan->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return redirect()->back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
        }
    }

    /**
     * Kirim WhatsApp notifikasi isolir
     */
    private function sendIsolirWhatsapp(\App\Models\Pelanggan $pelanggan, $nomorInvoice)
    {
        try {
            // Ambil template isolir-layanan
            $template = \App\Models\PesanTemplate::where('slug', 'isolir-layanan')
                                                 ->where('aktif', true)
                                                 ->first();

            if (!$template) {
                Log::warning('Template isolir-layanan tidak ditemukan atau tidak aktif');
                return ['success' => false, 'message' => 'Template pesan tidak ditemukan'];
            }

            // Ambil gateway WhatsApp dengan ID 1 (sesuai permintaan user)
            $gateway = \App\Models\WhatsappGateway::find(1);
            
            if (!$gateway || $gateway->status !== 'aktif') {
                Log::warning('WhatsApp gateway ID 1 tidak ditemukan atau tidak aktif');
                return ['success' => false, 'message' => 'Gateway WhatsApp tidak tersedia'];
            }

            // Ambil data invoice terkait
            $invoice = \App\Models\Invoice::where('pelanggan_id', $pelanggan->id)
                                        ->where('nomor_invoice', $nomorInvoice)
                                        ->first();

            // Get company data
            $perusahaan = \App\Models\Perusahaan::first();
            $namaPerusahaan = $perusahaan ? $perusahaan->perusahaan : 'ISP Provider';
            $alamatKantor = $perusahaan ? $perusahaan->alamat_kantor : 'Alamat kantor';
            $csPhone = $perusahaan ? $perusahaan->telp_kantor : '021-12345678';

            // Siapkan variables untuk template
            $variables = [
                'nama_pelanggan' => $pelanggan->nama_lengkap,
                'nomor_invoice' => $nomorInvoice,
                'total_tagihan' => $invoice ? $invoice->total_amount_format : 'Rp 0',
                'tanggal_jatuh_tempo' => $invoice ? \Carbon\Carbon::parse($invoice->tanggal_jatuh_tempo)->format('d/m/Y') : '-',
                'paket_layanan' => $pelanggan->layanan_data ? $pelanggan->layanan_data->nama_layanan : 'Layanan Internet',
                'cs_phone' => $csPhone,
                'alamat_kantor' => $alamatKantor,
                'nama_perusahaan' => $namaPerusahaan
            ];

            // Replace template variables
            $message = $this->replaceTemplateVariables($template->kont_template, $variables);

            // Validasi nomor WhatsApp pelanggan
            if (empty($pelanggan->no_hp_whatsapp)) {
                Log::warning('Pelanggan tidak memiliki nomor WhatsApp', [
                    'pelanggan_id' => $pelanggan->id,
                    'nama_pelanggan' => $pelanggan->nama_lengkap
                ]);
                return ['success' => false, 'message' => 'Pelanggan tidak memiliki nomor WhatsApp'];
            }

            // Format nomor HP
            $phoneNumber = $this->formatPhoneNumber($pelanggan->no_hp_whatsapp);

            // Kirim WhatsApp
            $result = $this->sendWhatsapp($gateway, $phoneNumber, $message);

            // Log hasil
            Log::info('WhatsApp isolir terkirim', [
                'pelanggan_id' => $pelanggan->id,
                'nama_pelanggan' => $pelanggan->nama_lengkap,
                'phone' => $phoneNumber,
                'success' => $result,
                'nomor_invoice' => $nomorInvoice
            ]);

            return ['success' => $result, 'message' => $result ? 'WhatsApp berhasil dikirim' : 'Gagal mengirim WhatsApp'];

        } catch (\Exception $e) {
            Log::error('Error sending WhatsApp isolir', [
                'pelanggan_id' => $pelanggan->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    /**
     * Isolir layanan pelanggan di Mikrotik
     */
    private function isolirMikrotikService(\App\Models\Pelanggan $pelanggan)
    {
        try {
            // Validasi pelanggan memiliki nomer layanan
            if (empty($pelanggan->nomer_layanan)) {
                return ['success' => false, 'message' => 'Pelanggan tidak memiliki nomor layanan'];
            }

            // Ambil mikrotik yang aktif
            $mikrotik = \App\Models\Mikrotik::where('is_active', true)
                                           ->whereIn('status', ['online', 'error', 'maintenance'])
                                           ->first();
            
            if (!$mikrotik) {
                return ['success' => false, 'message' => 'Tidak ada Mikrotik yang aktif'];
            }

            // Koneksi ke Mikrotik
            $config = new \RouterOS\Config([
                'host' => $mikrotik->host,
                'user' => $mikrotik->username,
                'pass' => $mikrotik->password,
                'port' => $mikrotik->api_port,
                'timeout' => 10
            ]);

            $client = new \RouterOS\Client($config);

            $username = $pelanggan->nomer_layanan;
            $disconnectSuccess = false;
            $disableSuccess = false;

            // 1. Disconnect active PPP session
            try {
                // Cari session dengan username exact
                $query = new \RouterOS\Query('/ppp/active/print');
                $query->where('name', $username);
                $activeSessions = $client->query($query)->read();

                // Jika tidak ditemukan, cari berdasarkan comment
                if (empty($activeSessions)) {
                    $searchPattern = "Pelanggan: {$pelanggan->nama_lengkap} - {$username}";
                    $query = new \RouterOS\Query('/ppp/active/print');
                    $allSessions = $client->query($query)->read();
                    
                    foreach ($allSessions as $session) {
                        if (isset($session['comment']) && strpos($session['comment'], $searchPattern) !== false) {
                            $activeSessions[] = $session;
                        }
                    }
                }

                if (!empty($activeSessions)) {
                    foreach ($activeSessions as $session) {
                        $removeQuery = new \RouterOS\Query('/ppp/active/remove');
                        $removeQuery->equal('.id', $session['.id']);
                        $client->query($removeQuery)->read();
                    }
                    $disconnectSuccess = true;
                    Log::info('PPP session berhasil diputus', [
                        'username' => $username,
                        'actual_username' => $activeSessions[0]['name'] ?? 'unknown',
                        'sessions_count' => count($activeSessions)
                    ]);
                } else {
                    $disconnectSuccess = true; // Tidak ada session aktif, anggap berhasil
                    Log::info('Tidak ada PPP session aktif untuk diputus', ['username' => $username]);
                }
            } catch (\Exception $e) {
                Log::warning('Gagal memutus PPP session', [
                    'username' => $username,
                    'error' => $e->getMessage()
                ]);
                // Lanjut ke step berikutnya meskipun disconnect gagal
                $disconnectSuccess = true;
            }

            // 2. Disable PPP secret
            try {
                // Cari secret dengan username exact
                $query = new \RouterOS\Query('/ppp/secret/print');
                $query->where('name', $username);
                $secrets = $client->query($query)->read();

                // Jika tidak ditemukan, cari berdasarkan comment
                if (empty($secrets)) {
                    $searchPattern = "Pelanggan: {$pelanggan->nama_lengkap} - {$username}";
                    $query = new \RouterOS\Query('/ppp/secret/print');
                    $allSecrets = $client->query($query)->read();
                    
                    foreach ($allSecrets as $secret) {
                        if (isset($secret['comment']) && strpos($secret['comment'], $searchPattern) !== false) {
                            $secrets[] = $secret;
                            Log::info('PPP secret ditemukan berdasarkan comment', [
                                'search_pattern' => $searchPattern,
                                'found_username' => $secret['name'] ?? 'unknown',
                                'comment' => $secret['comment'] ?? 'no comment'
                            ]);
                        }
                    }
                }

                if (!empty($secrets)) {
                    foreach ($secrets as $secret) {
                        $setQuery = new \RouterOS\Query('/ppp/secret/set');
                        $setQuery->equal('.id', $secret['.id']);
                        $setQuery->equal('disabled', 'yes');
                        $client->query($setQuery)->read();
                    }
                    $disableSuccess = true;
                    Log::info('PPP secret berhasil dinonaktifkan', [
                        'search_username' => $username,
                        'actual_username' => $secrets[0]['name'] ?? 'unknown',
                        'secrets_count' => count($secrets)
                    ]);
                } else {
                    Log::warning('PPP secret tidak ditemukan dengan username atau comment', [
                        'username' => $username,
                        'search_pattern' => "Pelanggan: {$pelanggan->nama_lengkap} - {$username}"
                    ]);
                    $disableSuccess = false;
                }
            } catch (\Exception $e) {
                Log::error('Gagal menonaktifkan PPP secret', [
                    'username' => $username,
                    'error' => $e->getMessage()
                ]);
                $disableSuccess = false;
            }

            // Tentukan hasil akhir
            $overallSuccess = $disconnectSuccess && $disableSuccess;

            return [
                'success' => $overallSuccess,
                'message' => $overallSuccess ? 
                    'Layanan berhasil diisolir (koneksi diputus dan secret dinonaktifkan)' : 
                    'Gagal mengisolir layanan sepenuhnya'
            ];

        } catch (\Exception $e) {
            Log::error('Error saat isolir Mikrotik service', [
                'pelanggan_id' => $pelanggan->id,
                'username' => $pelanggan->nomer_layanan,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return ['success' => false, 'message' => 'Error koneksi Mikrotik: ' . $e->getMessage()];
        }
    }

    /**
     * Enable layanan pelanggan setelah pembayaran
     */
    public function enablePelanggan(\App\Models\Pelanggan $pelanggan)
    {
        try {
            // Validasi hak akses - cek role user
            $user = auth()->user();
            $allowedRoles = ['administrator', 'admin'];
            
            if (!in_array($user->role, $allowedRoles)) {
                return redirect()->back()->with('error', 'Anda tidak memiliki akses untuk mengaktifkan layanan pelanggan. Fitur ini hanya tersedia untuk Administrator dan Admin.');
            }

            // Validasi pelanggan memiliki nomer layanan
            if (empty($pelanggan->nomer_layanan)) {
                return redirect()->back()->with('error', 'Pelanggan tidak memiliki nomor layanan');
            }

            // Log mulai proses enable
            Log::channel('pelanggan')->info('Memulai proses enable pelanggan', [
                'pelanggan_id' => $pelanggan->id,
                'nama_pelanggan' => $pelanggan->nama_lengkap,
                'nomer_layanan' => $pelanggan->nomer_layanan
            ]);

            // 1. Enable PPP secret di Mikrotik
            $mikrotikResult = $this->enableMikrotikService($pelanggan);

            // 2. Kirim WhatsApp konfirmasi aktivasi (opsional)
            $whatsappResult = $this->sendEnableWhatsapp($pelanggan);

            // Tentukan hasil keseluruhan
            $success = $mikrotikResult['success'];

            // Log hasil akhir
            Log::channel('pelanggan')->info('Proses enable pelanggan selesai', [
                'pelanggan_id' => $pelanggan->id,
                'nama_pelanggan' => $pelanggan->nama_lengkap,
                'mikrotik_success' => $mikrotikResult['success'],
                'whatsapp_success' => $whatsappResult['success'],
                'overall_success' => $success
            ]);

            if ($success) {
                $message = 'Layanan pelanggan berhasil diaktifkan kembali!';
                if ($whatsappResult['success']) {
                    $message .= ' WhatsApp konfirmasi aktivasi telah dikirim.';
                }
                return redirect()->back()->with('success', $message);
            } else {
                return redirect()->back()->with('error', 'Terjadi kesalahan saat mengaktifkan layanan pelanggan: ' . $mikrotikResult['message']);
            }

        } catch (\Exception $e) {
            Log::error('Error pada proses enable pelanggan', [
                'pelanggan_id' => $pelanggan->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            return redirect()->back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
        }
    }

    /**
     * Enable layanan pelanggan di Mikrotik (kebalikan dari isolir)
     */
    private function enableMikrotikService(\App\Models\Pelanggan $pelanggan)
    {
        try {
            // Validasi pelanggan memiliki nomer layanan
            if (empty($pelanggan->nomer_layanan)) {
                return ['success' => false, 'message' => 'Pelanggan tidak memiliki nomor layanan'];
            }

            // Ambil mikrotik yang aktif
            $mikrotik = \App\Models\Mikrotik::where('is_active', true)
                                           ->whereIn('status', ['online', 'error', 'maintenance'])
                                           ->first();
            
            if (!$mikrotik) {
                return ['success' => false, 'message' => 'Tidak ada Mikrotik yang aktif'];
            }

            // Koneksi ke Mikrotik
            $config = new \RouterOS\Config([
                'host' => $mikrotik->host,
                'user' => $mikrotik->username,
                'pass' => $mikrotik->password,
                'port' => $mikrotik->api_port,
                'timeout' => 10
            ]);

            $client = new \RouterOS\Client($config);
            $username = $pelanggan->nomer_layanan;

            // Enable PPP secret - SEDERHANA!
            $query = new \RouterOS\Query('/ppp/secret/print');
            $query->where('name', $username);
            $secrets = $client->query($query)->read();

            // Jika tidak ditemukan dengan username exact, cari berdasarkan comment
            if (empty($secrets)) {
                $searchPattern = "Pelanggan: {$pelanggan->nama_lengkap} - {$username}";
                $query = new \RouterOS\Query('/ppp/secret/print');
                $allSecrets = $client->query($query)->read();
                
                foreach ($allSecrets as $secret) {
                    if (isset($secret['comment']) && strpos($secret['comment'], $searchPattern) !== false) {
                        $secrets[] = $secret;
                        break; // Ambil yang pertama ketemu saja
                    }
                }
            }

            if (!empty($secrets)) {
                $secret = $secrets[0]; // Ambil secret pertama
                
                // Enable secret (set disabled = no)
                $setQuery = new \RouterOS\Query('/ppp/secret/set');
                $setQuery->equal('.id', $secret['.id']);
                $setQuery->equal('disabled', 'no');
                $client->query($setQuery)->read();
                
                Log::info('PPP secret berhasil diaktifkan', [
                    'username' => $username,
                    'actual_username' => $secret['name'] ?? 'unknown'
                ]);
                
                return ['success' => true, 'message' => 'PPP Secret berhasil diaktifkan'];
            } else {
                Log::warning('PPP secret tidak ditemukan untuk enable', ['username' => $username]);
                return ['success' => false, 'message' => 'PPP Secret tidak ditemukan'];
            }

        } catch (\Exception $e) {
            Log::error('Error saat enable Mikrotik service', [
                'pelanggan_id' => $pelanggan->id,
                'username' => $pelanggan->nomer_layanan,
                'error' => $e->getMessage()
            ]);

            return ['success' => false, 'message' => 'Error koneksi Mikrotik: ' . $e->getMessage()];
        }
    }

    /**
     * Kirim WhatsApp konfirmasi aktivasi layanan - SEDERHANA!
     */
    private function sendEnableWhatsapp(\App\Models\Pelanggan $pelanggan)
    {
        try {
            // Ambil gateway WhatsApp yang aktif
            $gateway = \App\Models\WhatsappGateway::where('status', 'aktif')->first();
            if (!$gateway) {
                return ['success' => false, 'message' => 'Tidak ada WhatsApp Gateway yang aktif'];
            }

            // Validasi nomor WhatsApp pelanggan
            if (empty($pelanggan->no_hp_whatsapp)) {
                return ['success' => false, 'message' => 'Pelanggan tidak memiliki nomor WhatsApp'];
            }

            // Ambil template WhatsApp untuk aktivasi layanan
            $template = \App\Models\PesanTemplate::where('slug', 'aktivasi-layanan')
                                                ->where('aktif', true)
                                                ->first();
            
            // Siapkan pesan
            if ($template) {
                // Gunakan template jika ada
                $perusahaan = \App\Models\Perusahaan::first();
                $variables = [
                    'nama_pelanggan' => $pelanggan->nama_lengkap,
                    'nomer_layanan' => $pelanggan->nomer_layanan,
                    'paket_layanan' => $pelanggan->layanan_data ? $pelanggan->layanan_data->nama_layanan : 'Layanan Internet',
                    'tanggal_aktivasi' => now()->format('d/m/Y H:i'),
                    'nama_perusahaan' => $perusahaan ? $perusahaan->perusahaan : 'ISP Provider'
                ];
                $message = $this->replaceTemplateVariables($template->kont_template, $variables);
            } else {
                // Pesan sederhana jika template tidak ada
                $message = "Halo {$pelanggan->nama_lengkap}! 🎉\n\n";
                $message .= "Layanan internet Anda telah diaktifkan kembali setelah konfirmasi pembayaran.\n\n";
                $message .= "Terima kasih atas kepercayaan Anda.\n\n";
                $message .= "Salam,\nCustomer Service";
            }
            
            // Format nomor HP dan kirim WhatsApp
            $phoneNumber = $this->formatPhoneNumber($pelanggan->no_hp_whatsapp);
            $result = $this->sendWhatsapp($gateway, $phoneNumber, $message);

            Log::info('WhatsApp aktivasi terkirim', [
                'pelanggan_id' => $pelanggan->id,
                'nama_pelanggan' => $pelanggan->nama_lengkap,
                'phone' => $phoneNumber,
                'success' => $result
            ]);

            return ['success' => $result, 'message' => $result ? 'WhatsApp aktivasi berhasil dikirim' : 'Gagal mengirim WhatsApp aktivasi'];

        } catch (\Exception $e) {
            Log::error('Error sending WhatsApp aktivasi', [
                'pelanggan_id' => $pelanggan->id,
                'error' => $e->getMessage()
            ]);
            
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    /**
     * Show auto billing settings admin interface
     */
    public function showAutoBillingSettings()
    {
        $settings = \App\Models\AutoBillingSetting::getActiveSettings();
        return view('admin.auto_billing_settings', compact('settings'));
    }
    
    /**
     * Save auto billing settings from admin interface
     */
    public function saveAutoBillingSettings(Request $request)
    {
        $request->validate([
            'generate_day' => 'required|integer|min:1|max:31',
            'due_date_mode' => 'required|in:fixed_days,custom_date,mixed',
            'default_due_days' => 'required|integer|min:1|max:365',
            'advance_generate' => 'boolean',
            'advance_days' => 'required_if:advance_generate,1|integer|min:0|max:31'
        ]);
        
        try {
            // Update settings
            \App\Models\AutoBillingSetting::where('active', true)->update([
                'generate_day' => $request->generate_day,
                'due_date_mode' => $request->due_date_mode,
                'default_due_days' => $request->default_due_days,
                'advance_generate' => $request->boolean('advance_generate'),
                'advance_days' => $request->advance_generate ? $request->advance_days : 0,
                'updated_at' => now()
            ]);
            
            // Clear cache
            \Cache::forget('auto_billing_last_run');
            
            // Log change
            \Log::info('Auto billing settings updated via admin interface', [
                'user_id' => auth()->id(),
                'new_settings' => $request->only(['generate_day', 'due_date_mode', 'default_due_days', 'advance_generate', 'advance_days'])
            ]);
            
            return redirect()->route('admin.auto_billing_settings')
                           ->with('success', 'Auto billing settings berhasil diupdate!');
                           
        } catch (\Exception $e) {
            \Log::error('Error updating auto billing settings', [
                'error' => $e->getMessage(),
                'user_id' => auth()->id()
            ]);
            
            return redirect()->back()
                           ->withErrors(['error' => 'Gagal update settings: ' . $e->getMessage()])
                           ->withInput();
        }
    }

    /**
     * Send bulk WhatsApp to selected invoices
     */
    public function bulkWhatsApp(Request $request)
    {
        $request->validate([
            'invoice_ids' => 'required|array',
            'invoice_ids.*' => 'exists:invoices,id'
        ]);

        $startTime = microtime(true);
        $results = [];
        $successCount = 0;
        $failedCount = 0;

        try {
            // Get template
            $template = \App\Models\PesanTemplate::where('slug', 'reminder-tagihan-bulanan')
                                               ->where('aktif', true)
                                               ->first();

            if (!$template) {
                return response()->json([
                    'success' => false,
                    'message' => 'Template "reminder-tagihan-bulanan" tidak ditemukan atau tidak aktif'
                ]);
            }

            // Get active WhatsApp gateway
            $gateway = \App\Models\WhatsappGateway::where('status', 'aktif')->first();
            
            if (!$gateway) {
                return response()->json([
                    'success' => false,
                    'message' => 'Tidak ada WhatsApp gateway yang aktif'
                ]);
            }

            // Get company info
            $perusahaan = \App\Models\Perusahaan::first();

            // Get invoices with customer data
            $invoices = Invoice::with(['pelanggan'])
                              ->whereIn('id', $request->invoice_ids)
                              ->whereHas('pelanggan', function($query) {
                                  $query->whereNotNull('no_hp_whatsapp');
                              })
                              ->get();

            foreach ($invoices as $invoice) {
                try {
                    // Prepare message variables
                    $variables = [
                        '{{nama_pelanggan}}' => $invoice->pelanggan->nama_lengkap ?? 'Pelanggan',
                        '{{nomor_invoice}}' => $invoice->nomor_invoice,
                        '{{tanggal_invoice}}' => $invoice->tanggal_invoice->format('d/m/Y'),
                        '{{tanggal_jatuh_tempo}}' => $invoice->tanggal_jatuh_tempo->format('d/m/Y'),
                        '{{total_tagihan}}' => 'Rp ' . number_format($invoice->total_amount, 0, ',', '.'),
                        '{{nama_layanan}}' => $this->getLayananNameSafe($invoice->pelanggan),
                        '{{nama_perusahaan}}' => $perusahaan->perusahaan ?? 'PT. Kami',
                        '{{kontak_perusahaan}}' => $perusahaan->telp_kantor ?? '',
                        '{{alamat_perusahaan}}' => $perusahaan->alamat_kantor ?? '',
                    ];

                    // Replace variables in template
                    $message = str_replace(
                        array_keys($variables),
                        array_values($variables),
                        $template->kont_template
                    );

                    // Format phone number to international format
                    $phoneNumber = $this->formatPhoneNumberForWhatsApp($invoice->pelanggan->no_hp_whatsapp);
                    
                    if (!$phoneNumber) {
                        throw new \Exception("Invalid phone number: {$invoice->pelanggan->no_hp_whatsapp}");
                    }

                    // Send WhatsApp message using API
                    $sendResult = $this->sendWhatsAppViaAPI($gateway, $phoneNumber, $message);

                    if ($sendResult['success']) {
                        $successCount++;
                        $results[] = [
                            'invoice_number' => $invoice->nomor_invoice,
                            'customer_name' => $invoice->pelanggan->nama_lengkap,
                            'phone_number' => $phoneNumber,
                            'status' => 'success',
                            'message' => 'Berhasil dikirim'
                        ];

                        // Log success
                        \Log::info('Bulk WhatsApp sent successfully', [
                            'invoice_id' => $invoice->id,
                            'invoice_number' => $invoice->nomor_invoice,
                            'customer' => $invoice->pelanggan->nama_lengkap,
                            'phone' => $phoneNumber
                        ]);

                        // Update gateway statistics
                        $gateway->increment('total_sent');

                    } else {
                        throw new \Exception($sendResult['message']);
                    }

                } catch (\Exception $e) {
                    $failedCount++;
                    $results[] = [
                        'invoice_number' => $invoice->nomor_invoice,
                        'customer_name' => $invoice->pelanggan->nama_lengkap,
                        'phone_number' => $invoice->pelanggan->no_hp_whatsapp ?? 'N/A',
                        'status' => 'failed',
                        'message' => $e->getMessage()
                    ];

                    // Log error
                    \Log::error('Bulk WhatsApp failed', [
                        'invoice_id' => $invoice->id,
                        'invoice_number' => $invoice->nomor_invoice,
                        'customer' => $invoice->pelanggan->nama_lengkap,
                        'phone' => $invoice->pelanggan->no_hp_whatsapp,
                        'error' => $e->getMessage()
                    ]);

                    // Update gateway statistics
                    $gateway->increment('total_failed');
                }

                // Rate limiting: 4 second delay between sends
                if (count($results) < count($invoices)) {
                    sleep(4);
                }
            }

            $endTime = microtime(true);
            $duration = round($endTime - $startTime, 2);

            // Log summary
            \Log::info('Bulk WhatsApp execution completed', [
                'total_processed' => count($invoices),
                'success_count' => $successCount,
                'failed_count' => $failedCount,
                'duration_seconds' => $duration,
                'executed_by' => auth()->user()->name ?? 'System'
            ]);

            return response()->json([
                'success' => true,
                'message' => "Pengiriman selesai! Berhasil: {$successCount}, Gagal: {$failedCount}",
                'details' => [
                    'total_processed' => count($invoices),
                    'success_count' => $successCount,
                    'failed_count' => $failedCount,
                    'duration_seconds' => $duration,
                    'results' => $results
                ]
            ]);

        } catch (\Exception $e) {
            \Log::error('Bulk WhatsApp critical error', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'executed_by' => auth()->user()->name ?? 'System'
            ]);

            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Format phone number to international format for WhatsApp
     */
    private function formatPhoneNumberForWhatsApp($phoneNumber)
    {
        // Remove any non-numeric characters
        $phone = preg_replace('/[^0-9]/', '', $phoneNumber);
        
        // Check if already in international format
        if (substr($phone, 0, 2) === '62') {
            return $phone;
        }
        
        // Convert from local format (08x) to international (628x)
        if (substr($phone, 0, 2) === '08') {
            return '62' . substr($phone, 1);
        }
        
        // If starts with 8 (without 0), add 62
        if (substr($phone, 0, 1) === '8') {
            return '62' . $phone;
        }
        
        return null; // Invalid format
    }

    /**
     * Send WhatsApp message via API
     */
    private function sendWhatsAppViaAPI($gateway, $phoneNumber, $message)
    {
        try {
            // Build the request data
            $requestData = [
                'api_key' => $gateway->api_key,
                'sender' => $gateway->sender_number,
                'number' => $phoneNumber,
                'message' => $message
            ];

            // Log request data for debugging
            \Log::info('WhatsApp API Request', [
                'gateway_name' => $gateway->nama_gateway ?? 'Unknown',
                'base_url' => $gateway->base_url,
                'sender' => $gateway->sender_number,
                'recipient' => $phoneNumber,
                'message_length' => strlen($message),
                'api_key_present' => !empty($gateway->api_key)
            ]);

            // Try POST method with form data first (most common)
            $response = \Illuminate\Support\Facades\Http::timeout(30)
                ->asForm()
                ->post($gateway->base_url . '/send-message', $requestData);
            
            // Log response for debugging
            \Log::info('WhatsApp API Form Response', [
                'status_code' => $response->status(),
                'response_body' => $response->body()
            ]);

            if ($response->successful()) {
                $responseData = $response->json();
                
                // Check response for success indicator
                if (isset($responseData['status']) && $responseData['status'] === true) {
                    return [
                        'success' => true,
                        'message' => 'Message sent successfully via POST form'
                    ];
                }
            }
            
            // If form POST fails, try JSON POST
            if ($response->status() === 400) {
                \Log::info('Form POST failed, trying JSON POST...');
                
                $jsonResponse = \Illuminate\Support\Facades\Http::timeout(30)
                    ->withHeaders([
                        'Content-Type' => 'application/json',
                        'Accept' => 'application/json'
                    ])
                    ->post($gateway->base_url . '/send-message', $requestData);
                
                \Log::info('WhatsApp API JSON Response', [
                    'status_code' => $jsonResponse->status(),
                    'response_body' => $jsonResponse->body()
                ]);
                
                if ($jsonResponse->successful()) {
                    $responseData = $jsonResponse->json();
                    
                    if (isset($responseData['status']) && $responseData['status'] === true) {
                        return [
                            'success' => true,
                            'message' => 'Message sent successfully via JSON POST'
                        ];
                    }
                }
                
                // If both POST methods fail, try GET
                \Log::info('POST methods failed, trying GET method...');
                
                $getUrl = $gateway->base_url . '/send-message?' . http_build_query($requestData);
                $getResponse = \Illuminate\Support\Facades\Http::timeout(30)->get($getUrl);
                
                \Log::info('WhatsApp API GET Response', [
                    'url' => $getUrl,
                    'status_code' => $getResponse->status(),
                    'response_body' => $getResponse->body()
                ]);
                
                if ($getResponse->successful()) {
                    $responseData = $getResponse->json();
                    
                    if (isset($responseData['status']) && $responseData['status'] === true) {
                        return [
                            'success' => true,
                            'message' => 'Message sent successfully via GET'
                        ];
                    }
                } else {
                    return [
                        'success' => false,
                        'message' => 'All methods failed. Last GET error: ' . $getResponse->status() . ' - ' . $getResponse->body()
                    ];
                }
            }
            
            // If we reach here, all methods returned success HTTP codes but API responded with failure
            return [
                'success' => false,
                'message' => 'API responded with failure: ' . $response->body()
            ];
            
        } catch (\Exception $e) {
            \Log::error('WhatsApp API Exception', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            
            return [
                'success' => false,
                'message' => 'Connection Error: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Get layanan name safely
     */
    private function getLayananNameSafe(\App\Models\Pelanggan $pelanggan)
    {
        try {
            if ($pelanggan->layanan_type === 'pppoe') {
                $layanan = \App\Models\LayananPppoe::find($pelanggan->layanan_id);
                return $layanan ? $layanan->nama_layanan : 'Layanan PPPoE';
            } elseif ($pelanggan->layanan_type === 'hotspot') {
                $layanan = \App\Models\LayananHotspot::find($pelanggan->layanan_id);
                return $layanan ? $layanan->nama_layanan : 'Layanan Hotspot';
            }
            return 'Layanan';
        } catch (\Exception $e) {
            \Log::error('Error getting layanan name: ' . $e->getMessage());
            return 'Layanan';
        }
    }
} 