<?php

namespace App\Http\Controllers;

use App\Models\UserLanguage;
use App\Models\User;
use App\Models\Language;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;

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

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

            // Filter by language code
            if ($request->has('language_code')) {
                $query->where('language_code', $request->get('language_code'));
            }

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

            // 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')) {
                $userLanguages = $query->get();
            } else {
                $perPage = $request->get('per_page', 15);
                $userLanguages = $query->paginate($perPage);
            }

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

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

            $validator = Validator::make($request->all(), [
                'user_language_id' => 'nullable|exists:user_languages,user_language_id', // ✅ ID for update
                'language_code' => 'required|exists:languages,language_code',
                'proficiency' => 'required|in:basic,intermediate,fluent,native',
                '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;

            $userLanguageId = $request->input('user_language_id');

            if ($userLanguageId) {
                // ✅ UPDATE - Check if language exists and belongs to user
                $existingLanguage = UserLanguage::where('user_language_id', $userLanguageId)
                    ->where('user_id', $user->user_id)
                    ->first();

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

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

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

                $existingLanguage->update($validated);
                $userLanguage = $existingLanguage->fresh(['language']);
                $message = 'Language updated successfully';
                $statusCode = 200;
            } else {
                // ✅ CREATE - Check if language already exists for user
                $existingLanguage = UserLanguage::where('user_id', $user->user_id)
                    ->where('language_code', $validated['language_code'])
                    ->first();

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

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

                $userLanguage = UserLanguage::create($validated);
                $userLanguage->load(['language']);
                $message = 'Language added successfully';
                $statusCode = 201;
            }

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

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

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

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

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

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

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

            // Prevent deletion of primary language if it's the only one
            if ($userLanguage->is_primary) {
                $otherLanguages = UserLanguage::where('user_id', $userLanguage->user_id)
                    ->where('user_language_id', '!=', $id)
                    ->exists();

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

            $userLanguage->delete();

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

    /**
     * Get languages for current user
     */
    public function getMyLanguages(Request $request): JsonResponse
    {
        try {
            $user = $request->user();
            $languages = UserLanguage::with('language')
                ->where('user_id', $user->user_id)
                ->orderBy('is_primary', 'desc')
                ->orderBy('proficiency', 'desc')
                ->orderBy('created_at', 'desc')
                ->get();

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

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

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

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

            $userLanguage->setAsPrimary();

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

    /**
     * Add multiple languages to user - USING PUT
     */
    public function addMultipleLanguages(Request $request): JsonResponse
    {
        try {
            $user = $request->user();

            $validator = Validator::make($request->all(), [
                'languages' => 'required|array|min:1',
                'languages.*.language_code' => 'required|exists:languages,language_code',
                'languages.*.proficiency' => 'required|in:basic,intermediate,fluent,native',
                'languages.*.is_primary' => 'boolean'
            ]);

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

            $validated = $validator->validated();

            $addedLanguages = [];
            $errors = [];

            foreach ($validated['languages'] as $languageData) {
                try {
                    // Check if language already exists for user
                    $existingLanguage = UserLanguage::where('user_id', $user->user_id)
                        ->where('language_code', $languageData['language_code'])
                        ->first();

                    if ($existingLanguage) {
                        // Update existing language
                        $existingLanguage->update($languageData);
                        $userLanguage = $existingLanguage->fresh('language');
                    } else {
                        // Create new language
                        $userLanguage = UserLanguage::create(array_merge($languageData, ['user_id' => $user->user_id]));
                        $userLanguage->load('language');
                    }

                    // If setting as primary, unset other primary languages
                    if (isset($languageData['is_primary']) && $languageData['is_primary']) {
                        UserLanguage::where('user_id', $user->user_id)
                            ->where('is_primary', true)
                            ->where('user_language_id', '!=', $userLanguage->user_language_id)
                            ->update(['is_primary' => false]);
                    }

                    $addedLanguages[] = $userLanguage;
                } catch (\Exception $e) {
                    $errors[] = "Failed to save language {$languageData['language_code']}: " . $e->getMessage();
                }
            }

            $response = [
                'success' => true,
                'message' => count($addedLanguages) . ' languages processed successfully',
                'data' => $addedLanguages
            ];

            if (!empty($errors)) {
                $response['warnings'] = $errors;
            }

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