<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Company;
use App\Models\User;
use App\Models\UserDevice;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller
{
    /**
     * Login user dan generate token
     */
    public function login(Request $request): JsonResponse
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required|string',
            'device_name' => 'nullable|string',
            // Device info for validation
            'device_id' => 'nullable|string|max:255',
            'device_model' => 'nullable|string|max:255',
            'device_brand' => 'nullable|string|max:255',
            'os_version' => 'nullable|string|max:255',
            'app_version' => 'nullable|string|max:255',
        ]);

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

        if (!$user || !Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'email' => ['Email atau password salah.'],
            ]);
        }

        // Check approval status
        if ($user->approval_status === 'pending') {
            return response()->json([
                'success' => false,
                'message' => 'Akun Anda masih menunggu persetujuan admin.',
                'approval_status' => 'pending',
            ], 403);
        }

        if ($user->approval_status === 'rejected') {
            return response()->json([
                'success' => false,
                'message' => 'Pendaftaran Anda ditolak. Alasan: ' . ($user->rejection_reason ?? 'Tidak ada alasan'),
                'approval_status' => 'rejected',
                'rejection_reason' => $user->rejection_reason,
            ], 403);
        }

        if (!$user->is_active) {
            throw ValidationException::withMessages([
                'email' => ['Akun Anda tidak aktif. Silakan hubungi administrator.'],
            ]);
        }

        // ========== DEVICE VALIDATION ==========
        // Check if device_id is provided and device validation is enabled
        $deviceId = $request->device_id;
        $company = $user->company;

        // Device validation check (minimal logging for production)

        if ($deviceId && $company) {
            // Super admin is exempt from device validation
            $isSuperAdmin = $user->hasRole('super_admin');

            // Check if this device is registered to another user
            $deviceUsedByOther = UserDevice::where('device_id', $deviceId)
                ->where('user_id', '!=', $user->id)
                ->whereIn('status', [UserDevice::STATUS_APPROVED, UserDevice::STATUS_PENDING])
                ->with('user')
                ->first();

            // Prepare device info for registration
            $deviceInfo = [
                'device_id' => $deviceId,
                'device_model' => $request->device_model,
                'device_brand' => $request->device_brand,
                'os_version' => $request->os_version,
                'app_version' => $request->app_version,
            ];
            $maxDevices = $company->max_devices_per_user ?? 3;

            if ($deviceUsedByOther && !$isSuperAdmin) {
                // Device is registered by another user
                if ($company->device_validation_enabled) {
                    // If device validation is ENABLED, block login
                    return response()->json([
                        'success' => false,
                        'message' => 'Device ini sudah terdaftar oleh user lain (' . ($deviceUsedByOther->user?->name ?? 'Unknown') . '). Satu device hanya dapat digunakan oleh satu user.',
                        'error_code' => 'device_used_by_other',
                    ], 403);
                }
                // If device validation is DISABLED:
                // - Don't register this device for current user (it belongs to another user)
                // - User can still login, but check-in/check-out will use their own registered device info
                // - This allows borrowing devices when validation is off
            } else {
                // Device is not registered to anyone else, register/update for this user
                UserDevice::registerDevice($user->id, $deviceId, $deviceInfo, $maxDevices);
            }
        }

        $deviceName = $request->device_name ?? 'mobile_app';
        $token = $user->createToken($deviceName)->plainTextToken;

        return response()->json([
            'success' => true,
            'message' => 'Login berhasil',
            'data' => [
                'user' => $this->formatUserData($user),
                'token' => $token,
            ],
        ]);
    }

    /**
     * Register user baru (self-registration)
     */
    public function register(Request $request): JsonResponse
    {
        $request->validate([
            'company_id' => 'required|exists:companies,id',
            'employee_id' => 'nullable|string',
            'nip' => 'nullable|string',
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|string|min:8|confirmed',
            'phone' => ['required', 'string', 'regex:/^(\+62|62|0)8[1-9][0-9]{6,10}$/'],
            'department' => 'nullable|string',
            'position' => 'nullable|string',
            'address' => 'required|string|max:500',
            'home_latitude' => 'nullable|numeric|between:-90,90',
            'home_longitude' => 'nullable|numeric|between:-180,180',
        ]);

        $user = User::create([
            'company_id' => $request->company_id,
            'employee_id' => $request->employee_id,
            'nip' => $request->nip,
            'name' => $request->name,
            'email' => $request->email,
            'password' => $request->password,
            'phone' => $request->phone,
            'role' => 'employee',
            'department' => $request->department,
            'position' => $request->position,
            'address' => $request->address,
            'home_latitude' => $request->home_latitude,
            'home_longitude' => $request->home_longitude,
            'is_active' => false, // Will be activated after approval
            'approval_status' => 'pending',
        ]);

        // Assign employee role
        $user->assignRole('employee');

        return response()->json([
            'success' => true,
            'message' => 'Pendaftaran berhasil. Silakan tunggu persetujuan dari admin.',
            'data' => [
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name,
                    'email' => $user->email,
                    'approval_status' => $user->approval_status,
                ],
            ],
        ], 201);
    }

    /**
     * Check registration/approval status
     */
    public function checkApprovalStatus(Request $request): JsonResponse
    {
        $request->validate([
            'email' => 'required|email',
        ]);

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

        if (!$user) {
            return response()->json([
                'success' => false,
                'message' => 'Email tidak ditemukan',
            ], 404);
        }

        return response()->json([
            'success' => true,
            'data' => [
                'email' => $user->email,
                'name' => $user->name,
                'approval_status' => $user->approval_status,
                'rejection_reason' => $user->rejection_reason,
                'approved_at' => $user->approved_at?->format('Y-m-d H:i:s'),
            ],
        ]);
    }

    /**
     * Get available companies for registration
     */
    public function companies(): JsonResponse
    {
        $companies = Company::where('is_active', true)
            ->select('id', 'name', 'code')
            ->orderBy('name')
            ->get();

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

    /**
     * Logout user (revoke current token)
     */
    public function logout(Request $request): JsonResponse
    {
        $request->user()->currentAccessToken()->delete();

        return response()->json([
            'success' => true,
            'message' => 'Logout berhasil',
        ]);
    }

    /**
     * Logout dari semua device
     */
    public function logoutAll(Request $request): JsonResponse
    {
        $request->user()->tokens()->delete();

        return response()->json([
            'success' => true,
            'message' => 'Logout dari semua perangkat berhasil',
        ]);
    }

    /**
     * Get profil user yang sedang login
     */
    public function profile(Request $request): JsonResponse
    {
        $user = $request->user();

        return response()->json([
            'success' => true,
            'data' => $this->formatUserData($user),
        ]);
    }

    /**
     * Update profil user
     */
    public function updateProfile(Request $request): JsonResponse
    {
        $user = $request->user();

        $request->validate([
            'name' => 'sometimes|string|max:255',
            'phone' => 'nullable|string',
            'address' => 'nullable|string',
            'home_latitude' => 'nullable|numeric|between:-90,90',
            'home_longitude' => 'nullable|numeric|between:-180,180',
            'avatar' => 'nullable|image|mimes:jpg,jpeg,png|max:2048',
        ]);

        $data = $request->only([
            'name',
            'phone',
            'address',
            'home_latitude',
            'home_longitude',
        ]);

        // Handle avatar upload
        if ($request->hasFile('avatar')) {
            try {
                // Use public_direct disk (no symlink needed for shared hosting)
                $disk = 'public_direct';
                $storageDisk = \Illuminate\Support\Facades\Storage::disk($disk);

                // Delete old avatar if exists
                if ($user->avatar && $storageDisk->exists($user->avatar)) {
                    $storageDisk->delete($user->avatar);
                }

                // Create avatars directory if not exists
                if (!$storageDisk->exists('avatars')) {
                    $storageDisk->makeDirectory('avatars');
                }

                // Store new avatar directly to public/avatars
                $avatarPath = $request->file('avatar')->store('avatars', $disk);

                if (!$avatarPath) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Gagal mengupload foto profil.',
                    ], 500);
                }

                $data['avatar'] = $avatarPath;
            } catch (\Exception $e) {
                return response()->json([
                    'success' => false,
                    'message' => 'Gagal mengupload foto profil: ' . $e->getMessage(),
                ], 500);
            }
        }

        $user->update($data);

        return response()->json([
            'success' => true,
            'message' => 'Profil berhasil diperbarui',
            'data' => $this->formatUserData($user->fresh()),
        ]);
    }

    /**
     * Update password
     */
    public function updatePassword(Request $request): JsonResponse
    {
        $request->validate([
            'current_password' => 'required|string',
            'password' => 'required|string|min:8|confirmed',
        ]);

        $user = $request->user();

        if (!Hash::check($request->current_password, $user->password)) {
            throw ValidationException::withMessages([
                'current_password' => ['Password saat ini salah.'],
            ]);
        }

        $user->update([
            'password' => $request->password,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Password berhasil diperbarui',
        ]);
    }

    /**
     * Update lokasi rumah
     */
    public function updateHomeLocation(Request $request): JsonResponse
    {
        $request->validate([
            'latitude' => 'required|numeric|between:-90,90',
            'longitude' => 'required|numeric|between:-180,180',
            'address' => 'nullable|string',
        ]);

        $user = $request->user();
        $company = $user->company;

        // Admin/SuperAdmin selalu diizinkan
        // Employee hanya diizinkan jika allow_employee_edit_home_location = true
        if (!$user->hasRole(['admin', 'super_admin'])) {
            if (!($company->allow_employee_edit_home_location ?? false)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Fitur edit lokasi rumah tidak diaktifkan oleh admin',
                ], 403);
            }
        }

        $user->update([
            'home_latitude' => $request->latitude,
            'home_longitude' => $request->longitude,
            'address' => $request->address ?? $user->address,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Lokasi rumah berhasil diperbarui',
            'data' => $this->formatUserData($user->fresh()),
        ]);
    }

    /**
     * Format user data for API response
     */
    private function formatUserData(User $user): array
    {
        $user->load('company');

        return [
            'id' => $user->id,
            'employee_id' => $user->employee_id,
            'nip' => $user->nip,
            'name' => $user->name,
            'email' => $user->email,
            'phone' => $user->phone,
            'role' => $user->role,
            'roles' => $user->getRoleNames(),
            'permissions' => $user->getAllPermissions()->pluck('name'),
            'department' => $user->department,
            'position' => $user->position,
            'address' => $user->address,
            'home_latitude' => $user->home_latitude,
            'home_longitude' => $user->home_longitude,
            'has_home_location' => $user->hasHomeLocation(),
            // Avatar stored directly in public/avatars (no symlink needed)
            'avatar' => $user->avatar ? asset($user->avatar) . '?v=' . ($user->updated_at?->timestamp ?? time()) : null,
            'is_active' => $user->is_active,
            'approval_status' => $user->approval_status,
            'company' => $user->company ? [
                'id' => $user->company->id,
                'name' => $user->company->name,
                'code' => $user->company->code,
                'allow_document_upload' => $user->company->allow_document_upload,
                'work_start_time' => $user->company->work_start_time?->format('H:i'),
                'work_end_time' => $user->company->work_end_time?->format('H:i'),
            ] : null,
            'created_at' => $user->created_at->format('Y-m-d H:i:s'),
        ];
    }
}
