<?php

namespace App\Http\Controllers;

use App\Models\City;
use App\Models\Province;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

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

            // Filter by province
            if ($request->has('province_id')) {
                $query->byProvince($request->get('province_id'));
            }

            // Filter by active status
            if ($request->has('active_only') && $request->boolean('active_only')) {
                $query->active();
            }

            // Search by city name
            if ($request->has('search')) {
                $search = $request->get('search');
                $query->search($search);
            }

            // Default order by
            $orderBy = $request->get('order_by', 'city_name');
            $orderDirection = $request->get('order_direction', 'asc');
            $query->orderBy($orderBy, $orderDirection);

            // Pagination
            $perPage = $request->get('per_page', 10);
            $cities = $query->paginate($perPage);

            return response()->json([
                'success' => true,
                'data' => $cities->items(),
                'pagination' => [
                    'current_page' => $cities->currentPage(),
                    'per_page' => $cities->perPage(),
                    'total' => $cities->total(),
                    'last_page' => $cities->lastPage(),
                ]
            ]);

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

    /**
 * Get cities for dropdown by province
 */
public function getCitiesForDropdown(Request $request): JsonResponse
{
    try {
        $request->validate([
            'province_id' => 'required|exists:provinces,province_id'
        ]);

        $cities = City::select('city_id', 'city_name', 'province_id')
            ->with(['province:province_id,province_name'])
            ->where('province_id', $request->province_id)
            ->where('is_active', true)
            ->orderBy('city_name', 'asc')
            ->get()
            ->map(function ($city) {
                return [
                    'id' => $city->city_id,
                    'name' => $city->city_name,
                    'province_name' => $city->province->province_name ?? 'N/A'
                ];
            });

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

    } catch (\Illuminate\Validation\ValidationException $e) {
        return response()->json([
            'success' => false,
            'message' => 'Validation failed',
            'errors' => $e->errors()
        ], 422);
    } catch (\Exception $e) {
        return response()->json([
            'success' => false,
            'message' => 'Failed to fetch cities dropdown list',
            'error' => config('app.debug') ? $e->getMessage() : null
        ], 500);
    }
}

/**
 * Get all cities for dropdown (without province filter)
 */
public function getAllCitiesForDropdown(Request $request): JsonResponse
{
    try {
        $query = City::select('city_id', 'city_name', 'province_id')
            ->with(['province:province_id,province_name'])
            ->where('is_active', true);

        // Search by city name
        if ($request->has('search') && $request->search) {
            $query->where('city_name', 'like', "%{$request->search}%");
        }

        $cities = $query->orderBy('city_name', 'asc')
            ->get()
            ->map(function ($city) {
                return [
                    'id' => $city->city_id,
                    'name' => $city->city_name,
                    'province_name' => $city->province->province_name ?? 'N/A'
                ];
            });

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

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

    /**
 * Get all cities without pagination
 */
public function getAll(Request $request): JsonResponse
{
    try {
        $query = City::with(['province', 'province.country']);

        // Filter by province
        if ($request->has('province_id')) {
            $query->byProvince($request->get('province_id'));
        }

        // Filter by active status
        if ($request->has('active_only') && $request->boolean('active_only')) {
            $query->active();
        }

        // Search by city name
        if ($request->has('search')) {
            $search = $request->get('search');
            $query->search($search);
        }

        // Default order by
        $orderBy = $request->get('order_by', 'city_name');
        $orderDirection = $request->get('order_direction', 'asc');
        $query->orderBy($orderBy, $orderDirection);

        // Get all cities without pagination
        $cities = $query->get();

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

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

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request): JsonResponse
    {
        try {
            $validated = $request->validate([
                'province_id' => 'required|exists:provinces,province_id',
                'city_name' => 'required|string|max:100',
                'is_active' => 'boolean'
            ]);

            $city = City::create($validated);
            $city->load(['province', 'province.country']);

            return response()->json([
                'success' => true,
                'message' => 'City created successfully',
                'data' => $city
            ], 201);

        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to create city',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

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

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

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

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

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id): JsonResponse
    {
        try {
            $city = City::find($id);

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

            $validated = $request->validate([
                'province_id' => 'sometimes|exists:provinces,province_id',
                'city_name' => 'sometimes|string|max:100',
                'is_active' => 'boolean'
            ]);

            $city->update($validated);
            $city->load(['province', 'province.country']);

            return response()->json([
                'success' => true,
                'message' => 'City updated successfully',
                'data' => $city
            ]);

        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update city',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id): JsonResponse
    {
        try {
            $city = City::find($id);

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

            $city->delete();

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

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

    /**
     * Get cities by province
     */
    public function getByProvince(string $provinceId): JsonResponse
    {
        try {
            $province = Province::find($provinceId);

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

            $cities = City::with('province')
                ->where('province_id', $provinceId)
                ->active()
                ->orderBy('city_name')
                ->get();

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

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

    /**
     * Search cities by name
     */
    public function search(Request $request): JsonResponse
    {
        try {
            $request->validate([
                'query' => 'required|string|min:2'
            ]);

            $cities = City::with(['province', 'province.country'])
                ->search($request->get('query'))
                ->active()
                ->orderBy('city_name')
                ->limit(20)
                ->get();

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

        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to search cities',
                'error' => config('app.debug') ? $e->getMessage() : null
            ], 500);
        }
    }
}
