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

import '../controls/linear_status_indicator.dart';
import '../controls/responsive_max_width.dart';
import '../controls/status_and_refresh_button.dart';
import '../globals.dart';
import '../models/circle_data.dart';
import '../models/connection.dart';
import '../models/exec_error.dart';
import '../routes.dart';
import '../services/connections_manager.dart';
import '../services/network_status_service.dart';
import '../utils/active_profile_selector.dart';
import '../utils/snackbar_builder.dart';

class CircleAddUsersScreen extends StatefulWidget {
  final String circleId;

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

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

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

  @override
  void initState() {
    super.initState();
    final manager =
        getIt<ActiveProfileSelector<ConnectionsManager>>().activeEntry.value;
    circleData =
        manager.getMyCircles().where((g) => g.id == widget.circleId).first;
  }

  Future<void> addUserToCircle(
    ConnectionsManager manager,
    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 manager
          .addUserToCircle(circleData, connection)
          .withResult((p0) => setState(() {}))
          .fold(
            onSuccess: (_) => 'Added $messageBase',
            onError: (error) => 'Error adding $messageBase: $error',
          );
      buildSnackbar(context, message);
    }
  }

  @override
  Widget build(BuildContext context) {
    _logger.finer('Build');
    final nss = getIt<NetworkStatusService>();
    final manager = context
        .watch<ActiveProfileSelector<ConnectionsManager>>()
        .activeEntry
        .value;
    final circleMembers = manager
        .getCircleMembers(circleData)
        .withError((e) => logError(e, _logger))
        .getValueOrElse(() => [])
        .toSet();
    final allContacts = manager.getMyContacts();
    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(manager, 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 (nss.connectionUpdateStatus.value) {
              return;
            }
            manager.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: StatusAndRefreshButton(
                        valueListenable: nss.connectionUpdateStatus,
                        refreshFunction: () async =>
                            manager.refreshCircleMemberships(circleData),
                      ),
                    )
                  ],
                ),
                StandardLinearProgressIndicator(nss.connectionUpdateStatus),
                Expanded(child: body),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
