<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\City;
use App\Models\Country;
use App\Models\County;
use App\Models\District;
use App\Models\Location;
use App\Models\LocationImage;
use App\Models\Province;
use App\Models\Village;
use App\Models\Zone;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;

class LocationController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $user = Auth::user();

        // Get filter parameters
        $status = $request->get('status', 'all');
        $category = $request->get('category');
        $search = $request->get('search');
        $sort = $request->get('sort', 'newest');

        // Build query
        $query = Location::where('submitted_by', $user->id)
            ->with(['categoryRelation', 'province', 'city', 'images', 'ratings']);

        // Apply filters
        if ($status !== 'all') {
            $query->where('status', $status);
        }

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

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

        // Apply sorting
        switch ($sort) {
            case 'oldest':
                $query->orderBy('created_at', 'asc');
                break;
            case 'title':
                $query->orderBy('title', 'asc');
                break;
            case 'status':
                $query->orderBy('status', 'asc');
                break;
            case 'rating':
                $query->withAvg('ratings', 'rating')->orderBy('ratings_avg_rating', 'desc');
                break;
            default:
                $query->orderBy('created_at', 'desc');
        }

        $locations = $query->paginate(12)->withQueryString();

        // Get statistics
        $stats = $this->getLocationStats($user);

        // Get categories for filter
        $categories = Category::orderBy('category_fa')->get();

        // Check if it's an AJAX request for infinite scroll
        if ($request->ajax()) {
            return response()->json([
                'html' => view('user.locations.partials.location-grid', compact('locations'))->render(),
                'hasMorePages' => $locations->hasMorePages(),
                'nextPageUrl' => $locations->nextPageUrl()
            ]);
        }

        return view('user.locations.index', compact('locations', 'stats', 'categories', 'status', 'category', 'search', 'sort'));
    }

    /**
     * Get location statistics for user
     */
    private function getLocationStats($user)
    {
        $total = Location::where('submitted_by', $user->id)->count();
        $approved = Location::where('submitted_by', $user->id)->where('status', 'approved')->count();
        $pending = Location::where('submitted_by', $user->id)->where('status', 'pending')->count();
        $rejected = Location::where('submitted_by', $user->id)->where('status', 'rejected')->count();

        $totalViews = Location::where('submitted_by', $user->id)->sum('views_count') ?? 0;
        $totalRatings = \DB::table('ratings')
            ->join('locations', 'ratings.location_id', '=', 'locations.id')
            ->where('locations.submitted_by', $user->id)
            ->count();

        $avgRating = \DB::table('ratings')
            ->join('locations', 'ratings.location_id', '=', 'locations.id')
            ->where('locations.submitted_by', $user->id)
            ->avg('ratings.rating') ?? 0;

        return [
            'total' => $total,
            'approved' => $approved,
            'pending' => $pending,
            'rejected' => $rejected,
            'total_views' => $totalViews,
            'total_ratings' => $totalRatings,
            'avg_rating' => round($avgRating, 1)
        ];
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $categories = Category::orderBy('category_fa')->get();
        $countries = Country::orderBy('name_fa')->get();
        $provinces = Province::where('country_id', 1)->orderBy('name_fa')->get(); // Default to Iran
        $counties = County::where('province_id', 1)->orderBy('name_fa')->get(); // Default to Tehran
        $cities = City::where('county_id', 1)->orderBy('name_fa')->get(); // Default to Tehran County
        $districts = District::where('county_id', 1)->orderBy('name_fa')->get(); // Default to Tehran County
        $villages = Village::where('district_id', 1)->orderBy('name_fa')->get(); // Default to first district
        $zones = Zone::where('city_id', 1)->orderBy('name_fa')->get(); // Default to Tehran City

        return view('user.locations.create', compact(
            'categories',
            'countries',
            'provinces',
            'counties',
            'cities',
            'districts',
            'villages',
            'zones'
        ));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'category_id' => 'required|exists:categories,id',
            'country_id' => 'required|exists:countries,id',
            'province_id' => 'required|exists:provinces,id',
            'county_id' => 'required|exists:counties,id',
            'city_id' => 'required|exists:cities,id',
            'latitude' => 'required|numeric',
            'longitude' => 'required|numeric',
            'address' => 'nullable|string|max:500',
            'phone' => 'nullable|string|max:20',
            'website' => 'nullable|url|max:255',
            'description' => 'nullable|string|max:2000',
            'images.*' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
        ]);

        $location = new Location;
        $location->title = $request->title;
        $location->category_id = $request->category_id;
        $location->country_id = $request->country_id;
        $location->province_id = $request->province_id;
        $location->county_id = $request->county_id;
        $location->city_id = $request->city_id;
        $location->latitude = $request->latitude;
        $location->longitude = $request->longitude;
        $location->address = $request->address;
        $location->phone = $request->phone;
        $location->website = $request->website;
        $location->description = $request->description;
        $location->status = 'pending';
        $location->submitted_by = Auth::id();
        $location->save();

        // Handle image uploads
        if ($request->hasFile('images')) {
            foreach ($request->file('images') as $image) {
                $filename = Str::uuid().'.'.$image->getClientOriginalExtension();

                // Create image instance and resize
                $img = Image::make($image)
                    ->resize(800, null, function ($constraint) {
                        $constraint->aspectRatio();
                        $constraint->upsize();
                    })
                    ->encode('jpg', 80);

                // Store image to storage
                Storage::disk('public')->put('locations/'.$filename, $img);

                // Save to database
                $locationImage = new LocationImage;
                $locationImage->location_id = $location->id;
                $locationImage->image = $filename;
                $locationImage->save();
            }
        }

        return redirect()->route('user.locations.index')
            ->with('success', 'مکان با موفقیت ثبت شد و در انتظار تایید می‌باشد.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $location = Location::with(['categoryRelation', 'country', 'province', 'county', 'city', 'images', 'submittedBy'])
            ->where('id', $id)
            ->where('submitted_by', Auth::id())
            ->firstOrFail();

        return view('user.locations.show', compact('location'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $location = Location::where('id', $id)
            ->where('submitted_by', Auth::id())
            ->firstOrFail();

        // Only allow editing of pending locations
        if ($location->status !== 'pending') {
            return redirect()->route('user.locations.show', $location->id)
                ->with('error', 'فقط مکان‌های در انتظار تایید قابل ویرایش هستند.');
        }

        $categories = Category::orderBy('category_fa')->get();
        $countries = Country::orderBy('name_fa')->get();
        $provinces = Province::where('country_id', $location->country_id)->orderBy('name_fa')->get();
        $counties = County::where('province_id', $location->province_id)->orderBy('name_fa')->get();
        $cities = City::where('county_id', $location->county_id)->orderBy('name_fa')->get();

        return view('user.locations.edit', compact('location', 'categories', 'countries', 'provinces', 'counties', 'cities'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $location = Location::where('id', $id)
            ->where('submitted_by', Auth::id())
            ->firstOrFail();

        // Only allow editing of pending locations
        if ($location->status !== 'pending') {
            return redirect()->route('user.locations.show', $location->id)
                ->with('error', 'فقط مکان‌های در انتظار تایید قابل ویرایش هستند.');
        }

        $request->validate([
            'title' => 'required|string|max:255',
            'category_id' => 'required|exists:categories,id',
            'country_id' => 'required|exists:countries,id',
            'province_id' => 'required|exists:provinces,id',
            'county_id' => 'required|exists:counties,id',
            'city_id' => 'required|exists:cities,id',
            'latitude' => 'required|numeric',
            'longitude' => 'required|numeric',
            'address' => 'nullable|string|max:500',
            'phone' => 'nullable|string|max:20',
            'website' => 'nullable|url|max:255',
            'description' => 'nullable|string|max:2000',
            'images.*' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
            'deleted_images.*' => 'nullable|exists:location_images,id',
        ]);

        $location->title = $request->title;
        $location->category_id = $request->category_id;
        $location->country_id = $request->country_id;
        $location->province_id = $request->province_id;
        $location->county_id = $request->county_id;
        $location->city_id = $request->city_id;
        $location->latitude = $request->latitude;
        $location->longitude = $request->longitude;
        $location->address = $request->address;
        $location->phone = $request->phone;
        $location->website = $request->website;
        $location->description = $request->description;
        $location->save();

        // Handle deleted images
        if ($request->has('deleted_images')) {
            foreach ($request->deleted_images as $imageId) {
                if (! empty($imageId)) {
                    $image = LocationImage::where('id', $imageId)
                        ->where('location_id', $location->id)
                        ->first();

                    if ($image) {
                        // Delete the file from storage
                        Storage::disk('public')->delete('locations/'.$image->image);
                        // Delete the record
                        $image->delete();
                    }
                }
            }
        }

        // Handle new image uploads
        if ($request->hasFile('images')) {
            foreach ($request->file('images') as $image) {
                $filename = Str::uuid().'.'.$image->getClientOriginalExtension();

                // Create image instance and resize
                $img = Image::make($image)
                    ->resize(800, null, function ($constraint) {
                        $constraint->aspectRatio();
                        $constraint->upsize();
                    })
                    ->encode('jpg', 80);

                // Store image to storage
                Storage::disk('public')->put('locations/'.$filename, $img);

                // Save to database
                $locationImage = new LocationImage;
                $locationImage->location_id = $location->id;
                $locationImage->image = $filename;
                $locationImage->save();
            }
        }

        return redirect()->route('user.locations.show', $location->id)
            ->with('success', 'مکان با موفقیت به‌روزرسانی شد.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $location = Location::where('id', $id)
            ->where('submitted_by', Auth::id())
            ->firstOrFail();

        // Only allow deletion of pending locations
        if ($location->status !== 'pending') {
            return redirect()->route('user.locations.index')
                ->with('error', 'فقط مکان‌های در انتظار تایید قابل حذف هستند.');
        }

        // Delete all associated images
        foreach ($location->images as $image) {
            Storage::disk('public')->delete('locations/'.$image->image);
            $image->delete();
        }

        // Delete location
        $location->delete();

        return redirect()->route('user.locations.index')
            ->with('success', 'مکان با موفقیت حذف شد.');
    }
}
