<?php

namespace Modules\Users\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\RedirectResponse;
use Modules\Users\Http\Requests\StoreUserRequest;
use Modules\Users\Http\Requests\UpdateUserRequest;
use Modules\Users\Services\UserService;
use Illuminate\Support\Facades\DB;

class UsersController extends Controller
{
    private UserService $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
        $this->authorizeResource(User::class, 'user');
    }

    /**
     * Display a listing of the resource.
     */
    public function index(Request $request): Response
    {
        $user = $request->user();

        // Only admin can access user management
        if ($user->role !== 'admin') {
            abort(403);
        }

        // Build query
        $query = User::query();

        // Apply filters
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%");
            });
        }

        if ($request->filled('role')) {
            $query->where('role', $request->role);
        }

        if ($request->filled('status')) {
            $query->where('is_active', $request->status === 'active');
        }

        $users = $query->with(['student', 'teacher', 'guardian'])
                      ->latest()
                      ->paginate(20);

        // Get role statistics
        $roleStats = $this->userService->getRoleStatistics();

        return Inertia::render('Users/Index', [
            'users' => $users,
            'roleStats' => $roleStats,
            'filters' => [
                'search' => $request->search,
                'role' => $request->role,
                'status' => $request->status,
            ],
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create(): Response
    {
        return Inertia::render('Users/Create');
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(StoreUserRequest $request): RedirectResponse
    {
        $validated = $request->validated();

        try {
            DB::beginTransaction();

            $user = $this->userService->createUser($validated);

            DB::commit();

            return redirect()
                ->route('users.show', $user)
                ->with('success', 'User created successfully.');

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withInput()
                ->withErrors(['error' => 'Failed to create user: ' . $e->getMessage()]);
        }
    }

    /**
     * Show the specified resource.
     */
    public function show(User $user): Response
    {
        $user->load(['student', 'teacher', 'guardian']);

        // Get user activity summary
        $activitySummary = $this->userService->getUserActivitySummary($user->id);

        // Get role-specific data
        $roleData = $this->userService->getRoleSpecificData($user);

        return Inertia::render('Users/Show', [
            'user' => $user,
            'activitySummary' => $activitySummary,
            'roleData' => $roleData,
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(User $user): Response
    {
        $user->load(['student', 'teacher', 'guardian']);

        return Inertia::render('Users/Edit', [
            'user' => $user,
        ]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(UpdateUserRequest $request, User $user): RedirectResponse
    {
        $validated = $request->validated();

        try {
            DB::beginTransaction();

            $this->userService->updateUser($user, $validated);

            DB::commit();

            return redirect()
                ->route('users.show', $user)
                ->with('success', 'User updated successfully.');

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withInput()
                ->withErrors(['error' => 'Failed to update user: ' . $e->getMessage()]);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(User $user): RedirectResponse
    {
        try {
            DB::beginTransaction();

            // Check if user can be deleted
            if (!$this->userService->canDeleteUser($user)) {
                return back()->withErrors(['error' => 'User cannot be deleted due to existing relationships.']);
            }

            // Soft delete by deactivating
            $user->update(['is_active' => false]);

            // Deactivate related profiles
            if ($user->student) {
                $user->student->update(['is_active' => false]);
            }
            if ($user->teacher) {
                $user->teacher->update(['is_active' => false]);
            }
            if ($user->guardian) {
                $user->guardian->update(['is_active' => false]);
            }

            DB::commit();

            return redirect()
                ->route('users.index')
                ->with('success', 'User deactivated successfully.');

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withErrors(['error' => 'Failed to deactivate user: ' . $e->getMessage()]);
        }
    }

    /**
     * Activate/Deactivate user
     */
    public function toggleStatus(User $user): RedirectResponse
    {
        $this->authorize('update', $user);

        try {
            DB::beginTransaction();

            $newStatus = !$user->is_active;
            $user->update(['is_active' => $newStatus]);

            // Update related profiles
            if ($user->student) {
                $user->student->update(['is_active' => $newStatus]);
            }
            if ($user->teacher) {
                $user->teacher->update(['is_active' => $newStatus]);
            }
            if ($user->guardian) {
                $user->guardian->update(['is_active' => $newStatus]);
            }

            DB::commit();

            $status = $newStatus ? 'activated' : 'deactivated';
            return back()->with('success', "User {$status} successfully.");

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withErrors(['error' => 'Failed to update user status: ' . $e->getMessage()]);
        }
    }

    /**
     * Reset user password
     */
    public function resetPassword(User $user): RedirectResponse
    {
        $this->authorize('update', $user);

        try {
            $newPassword = $this->userService->resetUserPassword($user);

            return back()->with('success', "Password reset successfully. New password: {$newPassword}");

        } catch (\Exception $e) {
            return back()
                ->withErrors(['error' => 'Failed to reset password: ' . $e->getMessage()]);
        }
    }

    /**
     * Get user activity logs
     */
    public function activityLogs(User $user): Response
    {
        $this->authorize('view', $user);

        $activityLogs = $this->userService->getUserActivityLogs($user->id);

        return Inertia::render('Users/ActivityLogs', [
            'user' => $user,
            'activityLogs' => $activityLogs,
        ]);
    }

    /**
     * Bulk operations
     */
    public function bulkAction(Request $request): RedirectResponse
    {
        $request->validate([
            'action' => 'required|in:activate,deactivate,delete',
            'user_ids' => 'required|array',
            'user_ids.*' => 'exists:users,id',
        ]);

        try {
            DB::beginTransaction();

            $count = $this->userService->bulkAction($request->action, $request->user_ids);

            DB::commit();

            return back()->with('success', "{$count} users processed successfully.");

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withErrors(['error' => 'Bulk operation failed: ' . $e->getMessage()]);
        }
    }

    /**
     * Export users data
     */
    public function export(Request $request): \Symfony\Component\HttpFoundation\BinaryFileResponse
    {
        $this->authorize('export', User::class);

        $filters = [
            'role' => $request->role,
            'status' => $request->status,
            'search' => $request->search,
        ];

        $filePath = $this->userService->exportUsers($filters);

        return response()->download($filePath)->deleteFileAfterSend();
    }

    /**
     * Import users data
     */
    public function import(Request $request): RedirectResponse
    {
        $this->authorize('import', User::class);

        $request->validate([
            'file' => 'required|file|mimes:csv,txt|max:2048',
        ]);

        try {
            DB::beginTransaction();

            $result = $this->userService->importUsers($request->file('file'));

            DB::commit();

            return back()->with('success', "Import completed. {$result['success']} users imported, {$result['errors']} errors.");

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withErrors(['error' => 'Import failed: ' . $e->getMessage()]);
        }
    }
}
