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

import '../controls/responsive_max_width.dart';
import '../controls/status_and_refresh_button.dart';
import '../globals.dart';
import '../models/auth/profile.dart';
import '../models/connection.dart';
import '../models/exec_error.dart';
import '../models/timeline_grouping_list_data.dart';
import '../riverpod_controllers/account_services.dart';
import '../riverpod_controllers/circles_repo_services.dart';
import '../riverpod_controllers/connection_manager_services.dart';
import '../riverpod_controllers/networking/network_status_services.dart';
import '../routes.dart';
import '../utils/snackbar_builder.dart';

class CircleAddUsersScreen extends ConsumerStatefulWidget {
  final String circleId;

  const CircleAddUsersScreen({super.key, required this.circleId});

  @override
  ConsumerState<CircleAddUsersScreen> createState() =>
      _CircleAddUsersScreenState();
}

class _CircleAddUsersScreenState extends ConsumerState<CircleAddUsersScreen> {
  static final _logger = Logger('$CircleAddUsersScreen');
  var filterText = '';
  late TimelineGroupingListData circleData;

  @override
  void initState() {
    super.initState();

    final profile = ref.read(activeProfileProvider);
    circleData = ref
        .read(timelineGroupingListProvider(profile, GroupingType.circle))
        .first;
  }

  Future<void> addUserToCircle(
    Profile profile,
    Connection connection,
  ) async {
    final messageBase = '${connection.name} from ${circleData.name}';
    final confirm = await showYesNoDialog(context, 'Add $messageBase?');
    if (context.mounted && confirm == true) {
      final message = await ref
          .read(circlesProvider(profile).notifier)
          .addConnectionToCircle(circleData, connection)
          .withResult((p0) => setState(() {}))
          .fold(
            onSuccess: (_) => 'Added $messageBase',
            onError: (error) => 'Error adding $messageBase: $error',
          );
      if (mounted) {
        buildSnackbar(context, message);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    _logger.finer('Build');
    final profile = ref.watch(activeProfileProvider);
    final loading = ref.watch(connectionsLoadingProvider(profile));
    final circleMembers = ref
        .read(circlesProvider(profile).notifier)
        .getCircleMembers(circleData)
        .withError((e) => logError(e, _logger))
        .getValueOrElse(() => [])
        .toSet();

    final allContacts = switch (ref.watch(myContactsProvider(profile))) {
      AsyncData(:final value) => value,
      _ => []
    };
    final filterTextLC = filterText.toLowerCase();
    final contacts = allContacts
        .where((c) => !circleMembers.contains(c))
        .where((c) =>
            filterText.isEmpty ||
            c.name.toLowerCase().contains(filterTextLC) ||
            c.handle.toLowerCase().contains(filterTextLC))
        .toList();
    contacts.sort((c1, c2) => c1.name.compareTo(c2.name));
    _logger.finer(
      () =>
          '# in circle: ${circleMembers.length} # Contacts: ${allContacts.length}, #filtered: ${contacts.length}',
    );
    late Widget body;
    if (contacts.isEmpty) {
      body = const SingleChildScrollView(
          physics: AlwaysScrollableScrollPhysics(),
          child: Center(
            child: Text('No contacts'),
          ));
    } else {
      body = ListView.separated(
          physics: const AlwaysScrollableScrollPhysics(),
          itemBuilder: (context, index) {
            final contact = contacts[index];
            return ListTile(
              onTap: () {
                context.pushNamed(ScreenPaths.userProfile,
                    pathParameters: {'id': contact.id});
              },
              title: Text(
                '${contact.name} (${contact.handle})',
                softWrap: true,
              ),
              subtitle: Text(
                'Last Status: ${contact.lastStatus?.toIso8601String() ?? "Unknown"}',
                softWrap: true,
              ),
              trailing: IconButton(
                  onPressed: () async =>
                      await addUserToCircle(profile, contact),
                  icon: const Icon(Icons.add)),
            );
          },
          separatorBuilder: (context, index) => const Divider(),
          itemCount: contacts.length);
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text('Add Users'),
      ),
      body: SafeArea(
        child: RefreshIndicator(
          onRefresh: () async {
            if (loading) {
              return;
            }
            ref
                .read(circlesProvider(profile).notifier)
                .refreshCircleMemberships(circleData);
            return;
          },
          child: ResponsiveMaxWidth(
            child: Column(
              children: [
                Text(
                  'Circle: ${circleData.name}',
                  style: Theme.of(context).textTheme.bodyLarge,
                  softWrap: true,
                ),
                Row(
                  children: [
                    Expanded(
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: TextField(
                          onChanged: (value) {
                            setState(() {
                              filterText = value.toLowerCase();
                            });
                          },
                          decoration: InputDecoration(
                            labelText: 'Filter By Name',
                            alignLabelWithHint: true,
                            border: OutlineInputBorder(
                              borderSide: BorderSide(
                                color: Theme.of(context).highlightColor,
                              ),
                              borderRadius: BorderRadius.circular(5.0),
                            ),
                          ),
                        ),
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: StatusAndRefreshButton3(
                        executing: loading,
                        refreshFunction: () async => ref
                            .read(circlesProvider(profile).notifier)
                            .refreshCircleMemberships(circleData),
                      ),
                    )
                  ],
                ),
                if (loading) const LinearProgressIndicator(),
                Expanded(child: body),
              ],
            ),
          ),
        ),
      ),
    );
  }
}