<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Receivable;
use App\Models\Order;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;

class ReceivableController extends Controller
{
    /**
     * Tampilkan daftar piutang
     */
    public function index(Request $request)
    {
        // Query builder
        $query = Receivable::with(['order.product', 'user'])
            ->orderBy('created_at', 'desc');

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

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

        // Filter berdasarkan tanggal jatuh tempo
        if ($request->filled('due_date_from')) {
            $query->where('due_date', '>=', $request->due_date_from);
        }

        if ($request->filled('due_date_to')) {
            $query->where('due_date', '<=', $request->due_date_to);
        }

        // Filter berdasarkan pencarian - perbaiki dengan grouping yang benar
        if ($request->filled('search') && trim($request->search) !== '') {
            $searchTerm = trim($request->search);
            $query->where(function ($q) use ($searchTerm) {
                $q->where('receivable_number', 'like', "%{$searchTerm}%")
                  ->orWhereHas('order', function ($q2) use ($searchTerm) {
                      $q2->where('customer_name', 'like', "%{$searchTerm}%")
                         ->orWhere('customer_email', 'like', "%{$searchTerm}%");
                      // Tambahkan pencarian ID jika search adalah numerik
                      if (is_numeric($searchTerm)) {
                          $q2->orWhere('id', $searchTerm);
                      }
                  })
                  ->orWhereHas('order.product', function ($q3) use ($searchTerm) {
                      $q3->where('product_title', 'like', "%{$searchTerm}%");
                  });
                // Tambahkan pencarian ID receivable jika search adalah numerik
                if (is_numeric($searchTerm)) {
                    $q->orWhere('id', $searchTerm);
                }
            });
        }

        // Pagination
        $itemsPerPage = (int) Setting::get('items_per_page', 10);
        $receivables = $query->paginate($itemsPerPage)->withQueryString();

        // Statistik
        $stats = [
            'total' => Receivable::count(),
            'pending' => Receivable::where('payment_status', 'pending')->count(),
            'partial' => Receivable::where('payment_status', 'partial')->count(),
            'paid' => Receivable::where('payment_status', 'paid')->count(),
            'overdue' => Receivable::overdue()->count(),
            'total_amount' => Receivable::sum('total_amount'),
            'paid_amount' => Receivable::sum('paid_amount'),
            'remaining_amount' => Receivable::sum('remaining_amount'),
        ];

        return view('admin.receivables.index', compact('receivables', 'stats'));
    }

    /**
     * Tampilkan detail piutang
     */
    public function show(Receivable $receivable)
    {
        $receivable->load(['order.product', 'user']);
        return view('admin.receivables.show', compact('receivable'));
    }

    /**
     * Tampilkan form tambah pembayaran
     */
    public function createPayment(Receivable $receivable)
    {
        $receivable->load(['order.product', 'user']);
        return view('admin.receivables.create-payment', compact('receivable'));
    }

    /**
     * Proses tambah pembayaran
     */
    public function storePayment(Request $request, Receivable $receivable)
    {
        $request->validate([
            'amount' => 'required|numeric|min:1|max:' . $receivable->remaining_amount,
            'notes' => 'nullable|string|max:500',
            'payment_date' => 'nullable|date|before_or_equal:today'
        ]);

        try {
            DB::beginTransaction();

            $amount = $request->amount;
            $notes = $request->notes;
            $paymentDate = $request->payment_date ?? now();

            // Tambah pembayaran
            $receivable->addPayment($amount, $notes);
            
            // syncOrderStatus() sudah dipanggil di addPayment()
            // Tidak perlu update manual lagi karena sudah di-handle di Receivable model

            // Kirim notifikasi
            try {
                $notificationService = new \App\Services\NotificationService();
                $notificationService->notifyReceivablePaymentReceived($receivable->fresh(), $amount);
                
                // Cek jika sudah lunas
                if ($receivable->fresh()->payment_status === 'paid') {
                    $notificationService->notifyReceivablePaidOff($receivable->fresh());
                }
            } catch (\Exception $e) {
                \Log::error('Failed to send receivable payment notification: ' . $e->getMessage());
            }

            DB::commit();

            return redirect()
                ->route('admin.receivables.show', $receivable)
                ->with('success', 'Pembayaran berhasil ditambahkan!');

        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()
                ->back()
                ->with('error', 'Gagal menambahkan pembayaran: ' . $e->getMessage());
        }
    }

    /**
     * Update tanggal jatuh tempo
     */
    public function updateDueDate(Request $request, Receivable $receivable)
    {
        $request->validate([
            'due_date' => 'required|date|after:today'
        ]);

        $receivable->update([
            'due_date' => $request->due_date
        ]);

        return redirect()
            ->route('admin.receivables.show', $receivable)
            ->with('success', 'Tanggal jatuh tempo berhasil diupdate!');
    }

    /**
     * Update catatan
     */
    public function updateNotes(Request $request, Receivable $receivable)
    {
        $request->validate([
            'notes' => 'nullable|string|max:1000'
        ]);

        $receivable->update([
            'notes' => $request->notes
        ]);

        return redirect()
            ->route('admin.receivables.show', $receivable)
            ->with('success', 'Catatan berhasil diupdate!');
    }

    /**
     * Batalkan piutang
     */
    public function cancel(Receivable $receivable)
    {
        if ($receivable->payment_status === 'paid') {
            return redirect()
                ->back()
                ->with('error', 'Piutang yang sudah lunas tidak bisa dibatalkan!');
        }

        $receivable->update([
            'status' => 'cancelled',
            'payment_status' => 'pending'
        ]);

        return redirect()
            ->route('admin.receivables.index')
            ->with('success', 'Piutang berhasil dibatalkan!');
    }

    /**
     * Export laporan piutang
     */
    public function export(Request $request)
    {
        $query = Receivable::with(['order.product', 'user'])
            ->orderBy('created_at', 'desc');

        // Apply same filters as index
        if ($request->filled('payment_status')) {
            $query->where('payment_status', $request->payment_status);
        }

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

        if ($request->filled('due_date_from')) {
            $query->where('due_date', '>=', $request->due_date_from);
        }

        if ($request->filled('due_date_to')) {
            $query->where('due_date', '<=', $request->due_date_to);
        }

        // Filter berdasarkan pencarian
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('receivable_number', 'like', "%{$search}%")
                  ->orWhereHas('order', function ($q2) use ($search) {
                      $q2->where('customer_name', 'like', "%{$search}%")
                         ->orWhere('customer_email', 'like', "%{$search}%");
                  })
                  ->orWhereHas('order.product', function ($q3) use ($search) {
                      $q3->where('product_title', 'like', "%{$search}%");
                  });
            });
        }

        $receivables = $query->get();

        // Generate HTML table dengan styling untuk Excel
        $html = '<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        table {
            border-collapse: collapse;
            width: 100%;
            font-family: Arial, sans-serif;
            font-size: 11px;
        }
        th {
            background-color: #4472C4;
            color: #FFFFFF;
            font-weight: bold;
            text-align: center;
            padding: 10px 8px;
            border: 1px solid #000000;
            vertical-align: middle;
        }
        td {
            padding: 8px;
            border: 1px solid #CCCCCC;
            vertical-align: middle;
        }
        tr:nth-child(even) {
            background-color: #F2F2F2;
        }
        .text-right {
            text-align: right;
        }
        .text-center {
            text-align: center;
        }
        .text-left {
            text-align: left;
        }
    </style>
</head>
<body>
    <table>
        <thead>
            <tr>
                <th>No. Piutang</th>
                <th>No. Order</th>
                <th>Customer</th>
                <th>Email</th>
                <th>Produk</th>
                <th>Quantity</th>
                <th class="text-right">Total Amount</th>
                <th class="text-right">Paid Amount</th>
                <th class="text-right">Remaining Amount</th>
                <th>Payment Status</th>
                <th>Due Date</th>
                <th>Status</th>
                <th>Created At</th>
            </tr>
        </thead>
        <tbody>';

        foreach ($receivables as $receivable) {
            $order = $receivable->order;
            $product = $order && $order->product ? $order->product : null;
            
            $html .= '<tr>';
            $html .= '<td>' . htmlspecialchars($receivable->receivable_number) . '</td>';
            $html .= '<td>' . htmlspecialchars($order->order_number ?? '-') . '</td>';
            $html .= '<td>' . htmlspecialchars($order->customer_name ?? '-') . '</td>';
            $html .= '<td>' . htmlspecialchars($order->customer_email ?? '-') . '</td>';
            $html .= '<td>' . htmlspecialchars($product->product_title ?? '-') . '</td>';
            $html .= '<td class="text-center">' . ($order->quantity ?? 1) . '</td>';
            $html .= '<td class="text-right">' . number_format($receivable->total_amount, 0, ',', '.') . '</td>';
            $html .= '<td class="text-right">' . number_format($receivable->paid_amount, 0, ',', '.') . '</td>';
            $html .= '<td class="text-right">' . number_format($receivable->remaining_amount, 0, ',', '.') . '</td>';
            $html .= '<td class="text-center">' . htmlspecialchars($receivable->payment_status_label ?? '-') . '</td>';
            $html .= '<td class="text-center">' . ($receivable->due_date ? $receivable->due_date->format('d/m/Y') : '-') . '</td>';
            $html .= '<td class="text-center">' . htmlspecialchars(ucfirst($receivable->status)) . '</td>';
            $html .= '<td>' . $receivable->created_at->format('d/m/Y H:i') . '</td>';
            $html .= '</tr>';
        }

        $html .= '</tbody>
    </table>
</body>
</html>';

        // Generate filename
        $filename = 'piutang_' . now()->format('Y-m-d_H-i-s') . '.xls';

        // Return response dengan header untuk Excel
        return response($html, 200)
            ->header('Content-Type', 'application/vnd.ms-excel')
            ->header('Content-Disposition', 'attachment; filename="' . $filename . '"')
            ->header('Cache-Control', 'max-age=0');
    }

    /**
     * Dashboard piutang
     */
    public function dashboard()
    {
        // Piutang yang jatuh tempo
        $overdueReceivables = Receivable::overdue()
            ->with(['order.product', 'user'])
            ->orderBy('due_date', 'asc')
            ->limit(10)
            ->get();

        // Piutang yang akan jatuh tempo (7 hari ke depan)
        $upcomingDue = Receivable::where('due_date', '<=', now()->addDays(7))
            ->where('due_date', '>', now())
            ->whereIn('payment_status', ['pending', 'partial'])
            ->with(['order.product', 'user'])
            ->orderBy('due_date', 'asc')
            ->limit(10)
            ->get();

        // Statistik bulanan
        $monthlyStats = Receivable::selectRaw('
                DATE_FORMAT(created_at, "%Y-%m") as month,
                COUNT(*) as total_count,
                SUM(total_amount) as total_amount,
                SUM(paid_amount) as paid_amount,
                SUM(remaining_amount) as remaining_amount
            ')
            ->where('created_at', '>=', now()->subMonths(12))
            ->groupBy('month')
            ->orderBy('month', 'desc')
            ->get();

        return view('admin.receivables.dashboard', compact(
            'overdueReceivables',
            'upcomingDue',
            'monthlyStats'
        ));
    }
}