<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\BailCheckin;
use App\Models\BailApplication;
use App\Models\CaseSuspect;
use App\Models\CaseEvidence;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Str;

class AuthController extends Controller
{
    /**
     * Handle user login and issue access token
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required',
        ]);

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

        // Log the login attempt for debugging
        \Log::info('Login attempt', ['email' => $request->email]);

        // Find user by email
        $user = User::where('email', $request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            \Log::warning('Invalid credentials', ['email' => $request->email]);
            return response()->json([
                'success' => false,
                'message' => 'The provided credentials are incorrect.'
            ], 401);
        }

        // Revoke previous tokens
        $user->tokens()->delete();

        // Create new access token
        $accessToken = $user->createToken('access_token')->plainTextToken;
        $refreshToken = Str::random(60);
        
        // Update refresh token using regular update method
        $user->update([
            'refresh_token' => $refreshToken,
            'refresh_token_expiry' => now()->addDays(30),
        ]);

        // Log successful token generation
        \Log::info('Login successful, tokens generated', ['user_id' => $user->id]);

        // Return response in the format expected by the mobile app
        return response()->json([
            'success' => true,
            'message' => 'Login successful',
            'user' => [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'rank' => $user->rank,
                'badge_number' => $user->badge_number,
                'station_id' => $user->station_id,
                'station_name' => $user->station ? $user->station->name : '',
                'is_officer' => $user->is_officer,
                'role' => $user->is_officer ? 'officer' : 'admin',
                'profile_picture' => $user->profile_picture,
            ],
            'token' => $accessToken, // For mobile app compatibility
            'access_token' => $accessToken, // Standard name
            'refresh_token' => $refreshToken,
            'token_type' => 'Bearer',
            'expires_in' => 3600, // 1 hour token expiry
        ]);
    }

    /**
     * Refresh the access token using refresh token
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function refreshToken(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'refresh_token' => 'required|string',
        ]);

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

        $refreshToken = $request->refresh_token;
        $user = User::where('refresh_token', $refreshToken)
                    ->where('refresh_token_expiry', '>', now())
                    ->first();

        if (!$user) {
            return response()->json([
                'message' => 'Invalid refresh token.'
            ], 401);
        }

        // Revoke previous tokens
        $user->tokens()->delete();

        // Generate refresh token
        $refreshToken = Str::random(60);
        $refreshTokenExpiry = now()->addDays(30);

        // Save refresh token
        $user->refresh_token = $refreshToken;
        $user->refresh_token_expiry = $refreshTokenExpiry;
        $user->save();

        // Create new token
        $token = $user->createToken('auth-token')->plainTextToken;

        // Log token creation
        \Log::info('Token generated successfully', ['user_id' => $user->id]);

        // Return response with user data and tokens
        return response()->json([
            'success' => true,
            'message' => 'Token refreshed successfully',
            'user' => [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'rank' => $user->rank,
                'badge_number' => $user->badge_number,
                'is_officer' => $user->is_officer,
            ],
            'token' => $token,
            'refresh_token' => $refreshToken,
            'token_type' => 'Bearer',
            'expires_in' => 3600, // 1 hour
        ]);
    }

    /**
     * Get authenticated user info
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function user(Request $request)
    {
        $user = $request->user();
        
        return response()->json([
            'id' => $user->id,
            'name' => $user->name,
            'email' => $user->email,
            'rank' => $user->rank,
            'badge_number' => $user->badge_number,
            'is_officer' => $user->is_officer,
        ]);
    }

    /**
     * Logout user and revoke token
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout(Request $request)
    {
        // Revoke all tokens
        $request->user()->tokens()->delete();
        
        return response()->json([
            'message' => 'Successfully logged out'
        ]);
    }

    /**
     * Get bail check-ins
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getBailCheckins(Request $request)
    {
        $checkins = BailCheckin::with(['bailApplication', 'bailApplication.suspect'])
                    ->orderBy('check_in_date', 'desc')
                    ->paginate(15);
                    
        return response()->json($checkins);
    }

    /**
     * Get today's bail check-ins
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getTodayBailCheckins(Request $request)
    {
        $today = now()->format('Y-m-d');
        
        $checkins = BailCheckin::with(['bailApplication', 'bailApplication.suspect'])
                    ->whereDate('check_in_date', $today)
                    ->orderBy('check_in_time', 'asc')
                    ->get();
                    
        return response()->json($checkins);
    }

    /**
     * Store a new bail check-in
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function storeBailCheckin(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'bail_application_id' => 'required|exists:bail_applications,id',
            'check_in_date' => 'required|date',
            'check_in_time' => 'required',
            'status' => 'required|in:attended,missed,excused',
            'notes' => 'nullable|string',
            'location' => 'nullable|string',
        ]);

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

        $checkin = BailCheckin::create([
            'bail_application_id' => $request->bail_application_id,
            'check_in_date' => $request->check_in_date,
            'check_in_time' => $request->check_in_time,
            'status' => $request->status,
            'notes' => $request->notes,
            'location' => $request->location,
            'officer_id' => $request->user()->id,
        ]);
        
        return response()->json([
            'message' => 'Check-in recorded successfully',
            'checkin' => $checkin
        ], 201);
    }

    /**
     * Get cases
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getCases(Request $request)
    {
        // Get cases assigned to the current officer
        $cases = \App\Models\Case::where('officer_id', $request->user()->id)
                ->orWhere('lead_investigator_id', $request->user()->id)
                ->with(['victims', 'suspects', 'statements'])
                ->orderBy('created_at', 'desc')
                ->paginate(15);
                
        return response()->json($cases);
    }

    /**
     * Get a specific case
     * 
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function getCase(Request $request, $id)
    {
        $case = \App\Models\Case::with([
                'victims', 'suspects', 'statements', 
                'evidence', 'reports', 'updates'
            ])
            ->findOrFail($id);
            
        // Check if user has access to this case
        if ($case->officer_id != $request->user()->id && 
            $case->lead_investigator_id != $request->user()->id && 
            $request->user()->role != 'admin') {
            return response()->json([
                'message' => 'You do not have permission to view this case'
            ], 403);
        }
        
        return response()->json($case);
    }

    /**
     * Get evidence
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getEvidence(Request $request)
    {
        $evidence = CaseEvidence::with(['case', 'collectedBy'])
                    ->orderBy('collection_date', 'desc')
                    ->paginate(15);
                    
        return response()->json($evidence);
    }

    /**
     * Upload evidence
     * 
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function uploadEvidence(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'case_id' => 'required|exists:cases,id',
            'tag_number' => 'required|string',
            'evidence_type' => 'required|string',
            'description' => 'required|string',
            'collection_date' => 'required|date',
            'collection_location' => 'required|string',
            'file' => 'required|file|max:10240', // 10MB max
        ]);

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

        // Store the file
        $path = $request->file('file')->store('evidence');
        
        // Create evidence record
        $evidence = CaseEvidence::create([
            'case_id' => $request->case_id,
            'tag_number' => $request->tag_number,
            'evidence_type' => $request->evidence_type,
            'description' => $request->description,
            'collection_date' => $request->collection_date,
            'collection_location' => $request->collection_location,
            'collected_by' => $request->user()->id,
            'status' => 'active',
            'photos' => json_encode([$path]),
        ]);
        
        return response()->json([
            'message' => 'Evidence uploaded successfully',
            'evidence' => $evidence
        ], 201);
    }
}
