import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';

import '../providers/auth_provider.dart';
import '../providers/profile_provider.dart';
import '../providers/supabase_provider.dart';
import '../utils/lock_enforcer.dart';
import '../screens/auth/login_screen.dart';
import '../screens/auth/signup_screen.dart';
import '../screens/admin/offices_screen.dart';
import '../screens/admin/user_management_screen.dart';
import '../screens/admin/geofence_test_screen.dart';
import '../screens/dashboard/dashboard_screen.dart';
import '../screens/notifications/notifications_screen.dart';
import '../screens/profile/profile_screen.dart';
import '../screens/shared/under_development_screen.dart';
import '../screens/tasks/task_detail_screen.dart';
import '../screens/tasks/tasks_list_screen.dart';
import '../screens/tickets/ticket_detail_screen.dart';
import '../screens/tickets/tickets_list_screen.dart';
import '../screens/workforce/workforce_screen.dart';
import '../widgets/app_shell.dart';
import '../screens/teams/teams_screen.dart';

final appRouterProvider = Provider<GoRouter>((ref) {
  final notifier = RouterNotifier(ref);
  ref.onDispose(notifier.dispose);

  return GoRouter(
    initialLocation: '/dashboard',
    refreshListenable: notifier,
    redirect: (context, state) {
      final authState = ref.read(authStateChangesProvider);
      final session = authState.when(
        data: (state) => state.session,
        loading: () => ref.read(sessionProvider),
        error: (error, _) => ref.read(sessionProvider),
      );
      final isAuthRoute =
          state.fullPath == '/login' || state.fullPath == '/signup';
      final isSignedIn = session != null;
      final profileAsync = ref.read(currentProfileProvider);
      final isAdminRoute = state.matchedLocation.startsWith('/settings');
      final isAdmin = profileAsync.maybeWhen(
        data: (profile) => profile?.role == 'admin',
        orElse: () => false,
      );

      if (!isSignedIn && !isAuthRoute) {
        return '/login';
      }
      if (isSignedIn && isAuthRoute) {
        return '/dashboard';
      }
      if (isAdminRoute && !isAdmin) {
        return '/tickets';
      }
      return null;
    },
    routes: [
      GoRoute(path: '/login', builder: (context, state) => const LoginScreen()),
      GoRoute(
        path: '/signup',
        builder: (context, state) => const SignUpScreen(),
      ),
      ShellRoute(
        builder: (context, state, child) => AppScaffold(child: child),
        routes: [
          GoRoute(
            path: '/settings/teams',
            builder: (context, state) => const TeamsScreen(),
          ),
          GoRoute(
            path: '/dashboard',
            builder: (context, state) => const DashboardScreen(),
          ),
          GoRoute(
            path: '/tickets',
            builder: (context, state) => const TicketsListScreen(),
            routes: [
              GoRoute(
                path: ':id',
                builder: (context, state) => TicketDetailScreen(
                  ticketId: state.pathParameters['id'] ?? '',
                ),
              ),
            ],
          ),
          GoRoute(
            path: '/tasks',
            builder: (context, state) => const TasksListScreen(),
            routes: [
              GoRoute(
                path: ':id',
                builder: (context, state) =>
                    TaskDetailScreen(taskId: state.pathParameters['id'] ?? ''),
              ),
            ],
          ),
          GoRoute(
            path: '/events',
            builder: (context, state) => const UnderDevelopmentScreen(
              title: 'Events',
              subtitle: 'Event monitoring is under development.',
              icon: Icons.event,
            ),
          ),
          GoRoute(
            path: '/announcements',
            builder: (context, state) => const UnderDevelopmentScreen(
              title: 'Announcement',
              subtitle: 'Operational broadcasts are coming soon.',
              icon: Icons.campaign,
            ),
          ),
          GoRoute(
            path: '/workforce',
            builder: (context, state) => const WorkforceScreen(),
          ),
          GoRoute(
            path: '/reports',
            builder: (context, state) => const UnderDevelopmentScreen(
              title: 'Reports',
              subtitle: 'Reporting automation is under development.',
              icon: Icons.analytics,
            ),
          ),
          GoRoute(
            path: '/settings/users',
            builder: (context, state) => const UserManagementScreen(),
          ),
          GoRoute(
            path: '/settings/offices',
            builder: (context, state) => const OfficesScreen(),
          ),
          GoRoute(
            path: '/settings/geofence-test',
            builder: (context, state) => const GeofenceTestScreen(),
          ),
          GoRoute(
            path: '/notifications',
            builder: (context, state) => const NotificationsScreen(),
          ),
          GoRoute(
            path: '/profile',
            builder: (context, state) => const ProfileScreen(),
          ),
        ],
      ),
    ],
  );
});

class RouterNotifier extends ChangeNotifier {
  RouterNotifier(this.ref) {
    _authSub = ref.listen(authStateChangesProvider, (previous, next) {
      // Enforce auth-level ban when a session becomes available.
      next.when(
        data: (authState) {
          final session = authState.session;
          if (session != null) {
            // Fire-and-forget enforcement (best-effort client-side sign-out)
            enforceLockForCurrentUser(ref.read(supabaseClientProvider));
          }
        },
        loading: () {},
        error: (error, _) {},
      );
      notifyListeners();
    });
    _profileSub = ref.listen(currentProfileProvider, (previous, next) {
      notifyListeners();
    });
  }

  final Ref ref;
  late final ProviderSubscription _authSub;
  late final ProviderSubscription _profileSub;

  @override
  void dispose() {
    _authSub.close();
    _profileSub.close();
    super.dispose();
  }
}
