<?php

namespace App\Http\Controllers;

use App\Models\Order;
use App\Models\Address;
use App\Models\Wishlist;
use App\Models\Review;
use App\Services\ShippingService;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class CustomerDashboardController extends Controller
{
    protected $shippingService;

    public function __construct(ShippingService $shippingService)
    {
        $this->shippingService = $shippingService;
    }

    public function index(): Response
    {
        $user = auth()->user();
        $recentOrders = $user->orders()->with(['items.product', 'payment'])->latest()->take(3)->get();
        $wishlistCount = $user->wishlists()->count();
        $ordersCount = $user->orders()->count();
        
        return Inertia::render('Dashboard/Index', [
            'recentOrders' => $recentOrders,
            'wishlistCount' => $wishlistCount,
            'ordersCount' => $ordersCount
        ]);
    }

    public function profile(): Response
    {
        return Inertia::render('Dashboard/Profile', [
            'status' => session('status'),
        ]);
    }

    public function addresses(): Response
    {
        $user = auth()->user();
        $addresses = $user->addresses()->orderBy('is_default', 'desc')->get();
        $provinces = $this->shippingService->getProvinces();

        return Inertia::render('Dashboard/Address', [
            'addresses' => $addresses,
            'provinces' => $provinces
        ]);
    }

    public function orders(Request $request): Response
    {
        $user = auth()->user();
        $status = $request->input('status', 'all');

        $query = $user->orders()
            ->with(['items.product.images', 'shipment', 'payment', 'subscriptions'])
            ->latest();

        if ($status !== 'all') {
            if ($status === 'paid') {
                $query->where(function($q) {
                    $q->where('status', 'paid')
                      ->orWhere(function($sub) {
                          $sub->where('status', 'waiting_payment')
                              ->whereHas('payment', function($p) {
                                  $p->whereNotNull('payment_proof');
                              });
                      });
                });
            } elseif ($status === 'waiting_payment') {
                $query->where('status', 'waiting_payment')
                      ->where(function($q) {
                          $q->whereHas('payment', function($p) {
                              $p->whereNull('payment_proof');
                          })->orWhereDoesntHave('payment');
                      });
            } else {
                $query->where('status', $status);
            }
        }

        $orders = $query->paginate(5)->withQueryString();

        return Inertia::render('Dashboard/Orders', [
            'orders' => $orders,
            'status' => $status,
            'manualBankDetails' => \App\Models\Setting::get('manual_bank_details', ''),
            'manualQrisImage' => \App\Models\Setting::get('manual_qris_image', ''),
            'payment_manual_bank_list' => \App\Models\Setting::get('payment_manual_bank_list', '[]'),
        ]);
    }

    public function wishlist(): Response
    {
        $user = auth()->user();
        $wishlist = $user->wishlists()
            ->with(['product.images'])
            ->latest()
            ->paginate(5)
            ->withQueryString();

        return Inertia::render('Dashboard/Wishlist', [
            'wishlist' => $wishlist
        ]);
    }

    public function reviews(): Response
    {
        $user = auth()->user();
        $reviews = $user->reviews()
            ->with('product')
            ->latest()
            ->get();

        // Get list of products bought but not yet reviewed
        $purchasedProductIds = Order::where('user_id', $user->id)
            ->whereIn('status', ['delivered', 'completed'])
            ->with('items')
            ->get()
            ->pluck('items')
            ->flatten()
            ->pluck('product_id')
            ->unique();

        $reviewedProductIds = $reviews->pluck('product_id')->unique();
        $pendingProductIds = $purchasedProductIds->diff($reviewedProductIds);

        $pendingReviews = \App\Models\Product::whereIn('id', $pendingProductIds)
            ->with('images')
            ->get();

        return Inertia::render('Dashboard/Reviews', [
            'reviews' => $reviews,
            'pendingReviews' => $pendingReviews
        ]);
    }

    public function paymentPage(int $id): Response
    {
        $user = auth()->user();
        $order = $user->orders()
            ->with(['items.product.images', 'shipment', 'payment'])
            ->findOrFail($id);

        return Inertia::render('Dashboard/PaymentPage', [
            'order' => $order,
            'manualBankDetails' => \App\Models\Setting::get('manual_bank_details', ''),
            'manualQrisImage' => \App\Models\Setting::get('manual_qris_image', ''),
            'payment_manual_bank_list' => \App\Models\Setting::get('payment_manual_bank_list', '[]'),
            'payment_midtrans_active' => \App\Models\Setting::get('payment_gateway_active', 'none') === 'midtrans',
            'payment_duitku_active' => \App\Models\Setting::get('payment_gateway_active', 'none') === 'duitku',
            'payment_tripay_active' => \App\Models\Setting::get('payment_gateway_active', 'none') === 'tripay',
        ]);
    }

    public function affiliates(): Response
    {
        $user = auth()->user();

        // Get all affiliate commissions for this user
        $commissions = $user->affiliateCommissions()
            ->with(['buyer', 'order'])
            ->latest()
            ->get();

        // Get all withdrawal requests for this user
        $withdrawals = \App\Models\WithdrawalRequest::where('user_id', $user->id)
            ->latest()
            ->get();

        // Calculate statistics
        // 1. Pending (Order is not completed yet)
        $pendingAmount = $commissions->filter(fn($c) => $c->status === 'pending')->sum('commission_amount');

        // 2. Available (Approved and not linked to any withdrawal request)
        $availableAmount = $commissions->filter(fn($c) => $c->status === 'approved' && is_null($c->withdrawal_request_id))->sum('commission_amount');

        // 3. Paid / Withdrawn (Status is withdrawn/paid)
        $withdrawnAmount = $commissions->filter(fn($c) => $c->status === 'paid')->sum('commission_amount');

        // 4. Requested / Processing (Linked to a pending withdrawal request)
        $requestedAmount = \App\Models\AffiliateCommission::where('affiliate_user_id', $user->id)
            ->whereNotNull('withdrawal_request_id')
            ->whereHas('withdrawalRequest', function($query) {
                $query->where('status', 'pending');
            })
            ->sum('commission_amount');

        $totalCommission = $commissions->sum('commission_amount');

        $products = \App\Models\Product::where('status', 'active')
            ->select(['id', 'name', 'slug', 'price', 'discount_percent', 'label', 'label_color'])
            ->latest()
            ->get()
            ->map(function($product) use ($user) {
                $product->short_code = \App\Models\ProductAffiliateLink::getOrCreateLink($user->id, $product->id);
                return $product;
            });

        return Inertia::render('Dashboard/Affiliates', [
            'affiliateCode' => $user->affiliate_code,
            'commissions' => $commissions,
            'withdrawals' => $withdrawals,
            'products' => $products,
            'stats' => [
                'total' => $totalCommission,
                'pending' => $pendingAmount,
                'available' => $availableAmount,
                'withdrawn' => $withdrawnAmount,
                'requested' => $requestedAmount
            ]
        ]);
    }

    public function trackOrder(Request $request, int $id)
    {
        $user = auth()->user();
        if ($user->role === 'admin') {
            $order = Order::with('shipment')->findOrFail($id);
        } else {
            $order = $user->orders()->with('shipment')->findOrFail($id);
        }
        $shipment = $order->shipment;

        $trackingNumber = $request->query('tracking_number') ?: ($shipment ? $shipment->tracking_number : null);

        if (empty($trackingNumber)) {
            return response()->json([
                'success' => false,
                'message' => 'Nomor resi pengiriman belum tersedia.'
            ], 404);
        }

        $courier = $shipment ? strtolower($shipment->courier) : 'jne';

        // Map general couriers to standard API courier codes if needed
        $biteshipCourier = $courier;
        if ($courier === 'j&t') {
            $biteshipCourier = 'jnt';
        }

        $activeAggregator = \App\Models\Setting::get('shipping_aggregator_active', 'none');
        if ($activeAggregator === 'none') {
            return response()->json([
                'success' => false,
                'message' => 'Layanan pelacakan paket (shipping aggregator) dinonaktifkan atau belum diatur di admin.'
            ], 400);
        }

        $history = [];
        $statusStr = 'in_transit';
        $errorMessage = null;

        try {
            if ($activeAggregator === 'biteship') {
                $apiKey = \App\Models\Setting::get('biteship_api_key', '');
                if (empty($apiKey)) {
                    return response()->json([
                        'success' => false,
                        'message' => 'API Key Biteship belum dikonfigurasi di admin.'
                    ], 400);
                }
                $authHeader = str_starts_with($apiKey, 'Bearer ') ? $apiKey : 'Bearer ' . $apiKey;
                $response = \Illuminate\Support\Facades\Http::withoutVerifying()->withHeaders([
                    'Authorization' => $authHeader,
                    'Content-Type' => 'application/json'
                ])->get("https://api.biteship.com/v1/trackings/{$trackingNumber}/couriers/{$biteshipCourier}");

                if ($response->successful()) {
                    $resData = $response->json();
                    $statusStr = $resData['status'] ?? 'in_transit';
                    if (isset($resData['history']) && is_array($resData['history'])) {
                        foreach ($resData['history'] as $item) {
                            $history[] = [
                                'date' => isset($item['updated_at']) ? \Illuminate\Support\Carbon::parse($item['updated_at'])->format('Y-m-d H:i:s') : '-',
                                'description' => $item['note'] ?? $item['status'] ?? ''
                            ];
                        }
                    }
                } else {
                    $resBody = $response->json();
                    $errorMessage = $resBody['error'] ?? $resBody['message'] ?? 'Gagal menghubungi server Biteship.';
                }
            } elseif ($activeAggregator === 'kiriminaja') {
                $apiKey = \App\Models\Setting::get('kiriminaja_api_key', '');
                if (empty($apiKey)) {
                    return response()->json([
                        'success' => false,
                        'message' => 'API Key KiriminAja belum dikonfigurasi di admin.'
                    ], 400);
                }
                $authHeader = str_starts_with($apiKey, 'Bearer ') ? $apiKey : 'Bearer ' . $apiKey;
                $baseUrl = $this->shippingService->getKiriminajaBaseUrl($apiKey);
                $response = \Illuminate\Support\Facades\Http::withoutVerifying()->withHeaders([
                    'Authorization' => $authHeader,
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ])->post("{$baseUrl}/api/mitra/v3/tracking", [
                    'order_id' => $trackingNumber
                ]);

                if ($response->successful()) {
                    $resData = $response->json();
                    if (isset($resData['status']) && $resData['status']) {
                        $manifests = null;
                        if (isset($resData['details']['manifest']) && is_array($resData['details']['manifest'])) {
                            $manifests = $resData['details']['manifest'];
                        } elseif (isset($resData['datas']['manifest']) && is_array($resData['datas']['manifest'])) {
                            $manifests = $resData['datas']['manifest'];
                        } elseif (isset($resData['manifest']) && is_array($resData['manifest'])) {
                            $manifests = $resData['manifest'];
                        }

                        if ($manifests) {
                            foreach ($manifests as $item) {
                                $dateStr = trim(($item['manifest_date'] ?? '') . ' ' . ($item['manifest_time'] ?? ''));
                                $history[] = [
                                    'date' => !empty($dateStr) ? $dateStr : '-',
                                    'description' => $item['manifest_description'] ?? $item['note'] ?? ''
                                ];
                            }
                        }
                        if (isset($resData['details']['delivered']) && $resData['details']['delivered']) {
                            $statusStr = 'delivered';
                        }
                    } else {
                        $errorMessage = $resData['text'] ?? $resData['message'] ?? 'Nomor resi tidak valid atau tidak ditemukan di KiriminAja.';
                    }
                } else {
                    $resBody = $response->json();
                    $errorMessage = $resBody['text'] ?? $resBody['message'] ?? 'Gagal menghubungi server KiriminAja.';
                }
            } elseif ($activeAggregator === 'binderbyte') {
                $apiKey = \App\Models\Setting::get('binderbyte_api_key', '');
                if (empty($apiKey)) {
                    return response()->json([
                        'success' => false,
                        'message' => 'API Key BinderByte belum dikonfigurasi di admin.'
                    ], 400);
                }

                $binderbyteCourier = $courier;
                if ($courier === 'j&t') {
                    $binderbyteCourier = 'jnt';
                }

                $response = \Illuminate\Support\Facades\Http::withoutVerifying()->get("https://api.binderbyte.com/v1/track", [
                    'api_key' => $apiKey,
                    'courier' => $binderbyteCourier,
                    'awb' => $trackingNumber
                ]);

                if ($response->successful()) {
                    $resData = $response->json();
                    if (isset($resData['status']) && $resData['status'] === 200 && isset($resData['data']['history'])) {
                        $rawHistory = $resData['data']['history'];
                        if (is_array($rawHistory)) {
                            foreach ($rawHistory as $item) {
                                $desc = $item['desc'] ?? '';
                                if (!empty($item['location'])) {
                                    $desc .= " (Lokasi: {$item['location']})";
                                }
                                $history[] = [
                                    'date' => $item['date'] ?? '-',
                                    'description' => $desc
                                ];
                            }
                        }
                        $statusSummary = $resData['data']['summary']['status'] ?? '';
                        if (strtolower($statusSummary) === 'delivered') {
                            $statusStr = 'delivered';
                        }
                    } else {
                        $errorMessage = $resData['message'] ?? 'Nomor resi tidak valid atau tidak ditemukan di BinderByte.';
                    }
                } else {
                    $resBody = $response->json();
                    $errorMessage = $resBody['message'] ?? 'Gagal menghubungi server BinderByte.';
                }
            } elseif ($activeAggregator === 'rajaongkir') {
                $apiKey = \App\Models\Setting::get('rajaongkir_api_key', '');
                if (empty($apiKey)) {
                    return response()->json([
                        'success' => false,
                        'message' => 'API Key RajaOngkir belum dikonfigurasi di admin.'
                    ], 400);
                }
                $response = \Illuminate\Support\Facades\Http::withoutVerifying()->withHeaders([
                    'key' => $apiKey
                ])->post("https://rajaongkir.komerce.id/api/v1/track/waybill", [
                    'awb' => $trackingNumber,
                    'courier' => $courier
                ]);

                if ($response->successful()) {
                    $resData = $response->json();
                    $rawHistory = $resData['data']['history'] ?? $resData['results']['history'] ?? $resData['history'] ?? null;
                    if (is_array($rawHistory)) {
                        foreach ($rawHistory as $item) {
                            $dateStr = trim(($item['date'] ?? '') . ' ' . ($item['time'] ?? ''));
                            $desc = $item['description'] ?? $item['note'] ?? '';
                            if (!empty($item['position'])) {
                                $desc .= " (Posisi: {$item['position']})";
                            }
                            $history[] = [
                                'date' => !empty($dateStr) ? $dateStr : '-',
                                'description' => $desc
                            ];
                        }
                    }
                    $statusSummary = $resData['data']['summary']['status'] ?? $resData['summary']['status'] ?? '';
                    if (strtolower($statusSummary) === 'delivered') {
                        $statusStr = 'delivered';
                    }
                } else {
                    $resBody = $response->json();
                    $errorMessage = $resBody['message'] ?? 'Gagal menghubungi server RajaOngkir.';
                }
            }
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error("Package tracking error for order {$id}: " . $e->getMessage());
            $errorMessage = $e->getMessage();
        }

        if (empty($history)) {
            return response()->json([
                'success' => false,
                'message' => $errorMessage ?: 'Tidak ada riwayat pengiriman yang ditemukan untuk nomor resi tersebut di API Aggregator.'
            ], 404);
        }

        // Sort history by date descending (newest first)
        usort($history, function($a, $b) {
            return strcmp($b['date'], $a['date']);
        });

        return response()->json([
            'success' => true,
            'courier' => $shipment->courier,
            'service' => $shipment->service,
            'tracking_number' => $trackingNumber,
            'status' => $statusStr,
            'history' => $history
        ]);
    }
}

