<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\Frame;
use App\Models\FrameCategory;
use App\Models\Lens;
use App\Models\LensCategory;
use App\Models\User;
use App\Models\Wishlist;
use Illuminate\Http\Request;

class CustomerController extends Controller
{
    /**
     * List all optical stores / vendors with GPS Nearby Distance calculation & search
     */
    public function getVendors(Request $request)
    {
        $query = User::where('role', 'vendor')
            ->where('status', true)
            ->with([
                'vendorProfile',
                'activeSubscription',
                'banners' => fn($q) => $q->where('is_active', true)->orderBy('sort_order'),
                'offers' => fn($q) => $q->where('is_active', true),
            ]);

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhereHas('vendorProfile', function ($vp) use ($search) {
                      $vp->where('vendor_name', 'like', "%{$search}%")
                         ->orWhere('city', 'like', "%{$search}%")
                         ->orWhere('address', 'like', "%{$search}%");
                  });
            });
        }

        if ($request->filled('city')) {
            $city = $request->city;
            $query->whereHas('vendorProfile', fn($vp) => $vp->where('city', 'like', "%{$city}%"));
        }

        $vendors = $query->get();

        // Calculate GPS distance if coordinates supplied
        $userLat = $request->input('latitude');
        $userLng = $request->input('longitude');

        $mappedVendors = $vendors->map(function ($vendor) use ($userLat, $userLng) {
            $profile = $vendor->vendorProfile;
            $distanceKm = null;

            if ($userLat && $userLng && $profile && $profile->latitude && $profile->longitude) {
                $theta = $userLng - $profile->longitude;
                $dist = sin(deg2rad($userLat)) * sin(deg2rad($profile->latitude)) +
                        cos(deg2rad($userLat)) * cos(deg2rad($profile->latitude)) * cos(deg2rad($theta));
                $dist = acos(min(max($dist, -1.0), 1.0));
                $dist = rad2deg($dist);
                $miles = $dist * 60 * 1.1515;
                $distanceKm = round($miles * 1.609344, 2);
            }

            $vendor->distance_km = $distanceKm;
            $vendor->frames_count = Frame::where('vendor_id', $vendor->id)->where('is_active', true)->count();
            $vendor->lenses_count = Lens::where('vendor_id', $vendor->id)->where('is_active', true)->count();

            return $vendor;
        });

        if ($userLat && $userLng) {
            $mappedVendors = $mappedVendors->sortBy(fn($v) => $v->distance_km ?? 999999)->values();
        }

        return response()->json([
            'success' => true,
            'data' => $mappedVendors,
        ]);
    }

    /**
     * Get single vendor profile, active banners, offers, catalog & product counts
     */
    public function getVendorDetails($id)
    {
        $vendor = User::where('id', $id)
            ->where('role', 'vendor')
            ->with([
                'vendorProfile',
                'activeSubscription',
                'banners' => fn($q) => $q->where('is_active', true)->orderBy('sort_order'),
                'offers' => fn($q) => $q->where('is_active', true),
            ])
            ->firstOrFail();

        $frames = Frame::where('vendor_id', $id)
            ->where('is_active', true)
            ->with(['category', 'subCategory'])
            ->latest()
            ->get();

        $lenses = Lens::where('vendor_id', $id)
            ->where('is_active', true)
            ->with(['category', 'subCategory'])
            ->latest()
            ->get();

        $frameCategories = FrameCategory::where('vendor_id', $id)
            ->orWhereNull('vendor_id')
            ->with('subCategories')
            ->get();

        $lensCategories = LensCategory::where('vendor_id', $id)
            ->orWhereNull('vendor_id')
            ->with('subCategories')
            ->get();

        return response()->json([
            'success' => true,
            'data' => [
                'vendor' => $vendor,
                'banners' => $vendor->banners,
                'offers' => $vendor->offers,
                'frame_categories' => $frameCategories,
                'lens_categories' => $lensCategories,
                'frames' => $frames,
                'lenses' => $lenses,
                'stats' => [
                    'total_frames' => $frames->count(),
                    'total_lenses' => $lenses->count(),
                ],
            ],
        ]);
    }

    /**
     * Browse Frames Catalog with Multi-Facet Filters
     */
    public function getFrames(Request $request)
    {
        $query = Frame::where('is_active', true)
            ->with(['vendor.vendorProfile', 'category', 'subCategory']);

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

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

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

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

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

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

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

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

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

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%")
                  ->orWhere('color', 'like', "%{$search}%");
            });
        }

        $frames = $query->latest()->paginate($request->input('per_page', 20));

        return response()->json([
            'success' => true,
            'data' => $frames,
        ]);
    }

    /**
     * Get Frame Details
     */
    public function getFrameDetails($id)
    {
        $frame = Frame::with(['vendor.vendorProfile', 'category', 'subCategory'])->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $frame,
        ]);
    }

    /**
     * Browse Contact Lenses Catalog
     */
    public function getLenses(Request $request)
    {
        $query = Lens::where('is_active', true)
            ->with(['vendor.vendorProfile', 'category', 'subCategory']);

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

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

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

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

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%")
                  ->orWhere('color', 'like', "%{$search}%");
            });
        }

        $lenses = $query->latest()->paginate($request->input('per_page', 20));

        return response()->json([
            'success' => true,
            'data' => $lenses,
        ]);
    }

    /**
     * Get Lens Details
     */
    public function getLensDetails($id)
    {
        $lens = Lens::with(['vendor.vendorProfile', 'category', 'subCategory'])->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $lens,
        ]);
    }

    /**
     * Get Catalog Filter Options (categories, shapes, rim types)
     */
    public function getFilterOptions(Request $request)
    {
        $vendorId = $request->input('vendor_id');

        $frameCategoriesQuery = FrameCategory::where('is_active', true)->with('subCategories');
        $lensCategoriesQuery = LensCategory::where('is_active', true)->with('subCategories');

        if ($vendorId) {
            $frameCategoriesQuery->where(function ($q) use ($vendorId) {
                $q->whereNull('vendor_id')->orWhere('vendor_id', $vendorId);
            });
            $lensCategoriesQuery->where(function ($q) use ($vendorId) {
                $q->whereNull('vendor_id')->orWhere('vendor_id', $vendorId);
            });
        }

        return response()->json([
            'success' => true,
            'data' => [
                'frame_categories' => $frameCategoriesQuery->get(),
                'lens_categories' => $lensCategoriesQuery->get(),
                'shapes' => ['Aviator', 'Round', 'Rectangle', 'Square', 'Wayfarer', 'Cat-Eye', 'Oval', 'Geometric'],
                'rim_types' => ['Full-rim', 'Half-rim', 'Rimless'],
                'genders' => ['Men', 'Women', 'Unisex', 'Kids'],
                'sizes' => ['Small', 'Medium', 'Large', 'Extra Large'],
                'lens_types' => ['Daily Disposable', 'Monthly Disposable', 'Quarterly', 'Yearly', 'Colored Power'],
            ],
        ]);
    }

    /**
     * Toggle Wishlist / Favorite
     */
    public function toggleWishlist(Request $request)
    {
        $request->validate([
            'item_type' => 'required|in:frame,lens',
            'item_id' => 'required|integer',
        ]);

        $userId = $request->user()->id;
        $exists = Wishlist::where('user_id', $userId)
            ->where('item_type', $request->item_type)
            ->where('item_id', $request->item_id)
            ->first();

        if ($exists) {
            $exists->delete();
            return response()->json([
                'success' => true,
                'is_favorited' => false,
                'message' => 'Removed from favorites.',
            ]);
        }

        Wishlist::create([
            'user_id' => $userId,
            'item_type' => $request->item_type,
            'item_id' => $request->item_id,
        ]);

        return response()->json([
            'success' => true,
            'is_favorited' => true,
            'message' => 'Added to favorites.',
        ]);
    }

    /**
     * Get User Wishlist
     */
    public function getWishlist(Request $request)
    {
        $userId = $request->user()->id;
        $wishlists = Wishlist::where('user_id', $userId)->get();

        $frameIds = $wishlists->where('item_type', 'frame')->pluck('item_id');
        $lensIds = $wishlists->where('item_type', 'lens')->pluck('item_id');

        $frames = Frame::whereIn('id', $frameIds)->with('vendor.vendorProfile')->get();
        $lenses = Lens::whereIn('id', $lensIds)->with('vendor.vendorProfile')->get();

        return response()->json([
            'success' => true,
            'data' => [
                'frames' => $frames,
                'lenses' => $lenses,
            ],
        ]);
    }

    /**
     * Get Ongoing & Upcoming Store Mega Sales & Events
     */
    public function getEvents(Request $request)
    {
        $query = \App\Models\VendorEvent::where('is_active', true)
            ->where('end_date', '>=', now()->toDateString())
            ->with(['vendor.vendorProfile'])
            ->orderBy('start_date');

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

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%")
                  ->orWhere('location', 'like', "%{$search}%");
            });
        }

        $events = $query->paginate($request->input('per_page', 20));

        return response()->json([
            'success' => true,
            'data' => $events,
        ]);
    }

    /**
     * Get Single Event Details
     */
    public function getEventDetails($id)
    {
        $event = \App\Models\VendorEvent::where('is_active', true)
            ->with(['vendor.vendorProfile'])
            ->findOrFail($id);

        return response()->json([
            'success' => true,
            'data' => $event,
        ]);
    }

    /**
     * Get Customer Notifications (SuperAdmin & Optical Stores)
     */
    public function getNotifications(Request $request)
    {
        $notifications = \App\Models\AppNotification::where(function ($q) {
            $q->whereIn('target_audience', ['all_users', 'both'])
              ->orWhere('sender_role', 'vendor');
        })
        ->with('sender.vendorProfile')
        ->latest()
        ->paginate($request->input('per_page', 25));

        return response()->json([
            'success' => true,
            'data' => $notifications,
        ]);
    }
}
