<?php

namespace App\Http\Controllers;

use App\Models\Address;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;

class AddressController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request): JsonResponse
    {
        try {
            $query = Address::with(['user', 'city', 'province', 'country']);

            // Filter by user
            if ($request->has('user_id')) {
                $query->where('user_id', $request->get('user_id'));
            }

            // Filter by address type
            if ($request->has('address_type')) {
                $query->where('address_type', $request->get('address_type'));
            }

            // Filter by primary addresses only
            if ($request->has('primary_only') && $request->boolean('primary_only')) {
                $query->where('is_primary', true);
            }

            // Order by
            $orderBy = $request->get('order_by', 'created_at');
            $orderDirection = $request->get('order_direction', 'desc');
            $query->orderBy($orderBy, $orderDirection);

            // Get all or paginate
            if ($request->has('paginate') && !$request->boolean('paginate')) {
                $addresses = $query->get();
            } else {
                $perPage = $request->get('per_page', 15);
                $addresses = $query->paginate($perPage);
            }

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

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch addresses',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
 * Get addresses for specific user
 */
public function getUserAddresses(Request $request, string $userId): JsonResponse
{
    try {
        // Check if user exists
        $user = User::find($userId);
        if (!$user) {
            return response()->json([
                'success' => false,
                'message' => 'User not found'
            ], 404);
        }

        $addresses = Address::with(['city', 'province', 'country'])
            ->where('user_id', $userId)
            ->orderBy('is_primary', 'desc')
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json([
            'success' => true,
            'data' => $addresses,
            'user' => [
                'user_id' => $user->user_id,
                'name' => $user->name,
                'email' => $user->email
            ],
            'count' => $addresses->count()
        ]);

    } catch (\Exception $e) {
        return response()->json([
            'success' => false,
            'message' => 'Failed to fetch user addresses',
            'error' => config('app.debug') ? $e->getMessage() : null
        ], 500);
    }
}

    /**
     * Save address - Create or Update using single PUT API
     */
    public function saveAddress(Request $request): JsonResponse
    {
        try {
            $user = Auth::user();

            if (!$user) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthenticated. Please login first.'
                ], 401);
            }

            $validator = Validator::make($request->all(), [
                'address_id' => 'nullable|exists:addresses,address_id', // ✅ ID for update
                'address_type' => 'required|in:home,work,other',
                'street_address' => 'required|string|max:255',
                'city_id' => 'required|exists:cities,city_id',
                'province_id' => 'required|exists:provinces,province_id',
                'country_id' => 'required|exists:countries,country_id',
                'postal_code' => 'required|string|max:20',
                'latitude' => 'nullable|numeric|between:-90,90',
                'longitude' => 'nullable|numeric|between:-180,180',
                'is_primary' => 'boolean'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $validated = $validator->validated();
            $validated['user_id'] = $user->user_id;

            $addressId = $request->input('address_id');

            if ($addressId) {
                // ✅ UPDATE - Check if address exists and belongs to user
                $existingAddress = Address::where('address_id', $addressId)
                    ->where('user_id', $user->user_id)
                    ->first();

                if (!$existingAddress) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Address not found or unauthorized'
                    ], 404);
                }

                // If setting as primary, unset other primary addresses
                if (isset($validated['is_primary']) && $validated['is_primary']) {
                    Address::where('user_id', $user->user_id)
                        ->where('is_primary', true)
                        ->where('address_id', '!=', $addressId)
                        ->update(['is_primary' => false]);
                }

                // Remove address_id from update data
                unset($validated['address_id']);

                $existingAddress->update($validated);
                $address = $existingAddress->fresh(['city', 'province', 'country']);
                $message = 'Address updated successfully';
                $statusCode = 200;
            } else {
                // ✅ CREATE - Check if address type already exists
                $existingAddressType = Address::where('user_id', $user->user_id)
                    ->where('address_type', $validated['address_type'])
                    ->first();

                if ($existingAddressType) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Address type already exists. Please use update with address_id.'
                    ], 422);
                }

                // If setting as primary, unset other primary addresses
                if (isset($validated['is_primary']) && $validated['is_primary']) {
                    Address::where('user_id', $user->user_id)
                        ->where('is_primary', true)
                        ->update(['is_primary' => false]);
                }

                $address = Address::create($validated);
                $address->load(['city', 'province', 'country']);
                $message = 'Address created successfully';
                $statusCode = 201;
            }

            return response()->json([
                'success' => true,
                'message' => $message,
                'data' => $address
            ], $statusCode);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to save address',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show(Request $request, string $id): JsonResponse
    {
        try {
            $address = Address::with(['user', 'city', 'province', 'country'])->find($id);

            if (!$address) {
                return response()->json([
                    'success' => false,
                    'message' => 'Address not found'
                ], 404);
            }

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

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch address',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Request $request, string $id): JsonResponse
    {
        try {
            $address = Address::find($id);

            if (!$address) {
                return response()->json([
                    'success' => false,
                    'message' => 'Address not found'
                ], 404);
            }

            // Check if user owns this address
            $currentUser = Auth::user();
            if (!$currentUser || $currentUser->user_id != $address->user_id) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized to delete this address'
                ], 403);
            }

            // Prevent deletion of primary address if it's the only one
            if ($address->is_primary) {
                $otherAddresses = Address::where('user_id', $address->user_id)
                    ->where('address_id', '!=', $id)
                    ->exists();

                if (!$otherAddresses) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Cannot delete the only address. Please add another address first.'
                    ], 422);
                }
            }

            $address->delete();

            return response()->json([
                'success' => true,
                'message' => 'Address deleted successfully'
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete address',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Get addresses for current user
     */
    public function getMyAddresses(Request $request): JsonResponse
    {
        try {
            $user = Auth::user();

            if (!$user) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthenticated. Please login first.'
                ], 401);
            }

            $addresses = Address::with(['city', 'province', 'country'])
                ->where('user_id', $user->user_id)
                ->orderBy('is_primary', 'desc')
                ->orderBy('created_at', 'desc')
                ->get();

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

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch user addresses',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Set address as primary - USING PUT
     */
    public function setAsPrimary(Request $request, string $id): JsonResponse
    {
        try {
            $address = Address::find($id);

            if (!$address) {
                return response()->json([
                    'success' => false,
                    'message' => 'Address not found'
                ], 404);
            }

            // Check if user owns this address
            $currentUser = Auth::user();
            if (!$currentUser || $currentUser->user_id != $address->user_id) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized to update this address'
                ], 403);
            }

            $address->setAsPrimary();

            return response()->json([
                'success' => true,
                'message' => 'Address set as primary successfully',
                'data' => $address->fresh(['city', 'province', 'country'])
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to set address as primary',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }
}
