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

import '../controls/linear_status_indicator.dart';
import '../controls/padding.dart';
import '../controls/responsive_max_width.dart';
import '../controls/standard_appbar.dart';
import '../controls/status_and_refresh_button.dart';
import '../globals.dart';
import '../models/circle_data.dart';
import '../models/connection.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 CircleEditorScreen extends StatefulWidget {
  final String circleId;

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

  @override
  State<CircleEditorScreen> createState() => _CircleEditorScreenState();
}

class _CircleEditorScreenState extends State<CircleEditorScreen> {
  final circleTextController = TextEditingController();
  var processingUpdate = false;
  var allowNameEditing = false;
  var filterText = '';
  late CircleData circleData;

  Future<void> updateCircleName(
      BuildContext context, ConnectionsManager manager) async {
    processingUpdate = true;
    final updated = circleTextController.text;
    if (circleTextController.text != circleData.name) {
      final confirm = await showYesNoDialog(context,
          'Change the circle name from ${circleData.name} to $updated?');
      if (context.mounted && confirm == true) {
        await manager.renameCircle(widget.circleId, updated).match(
            onSuccess: (updatedCircleData) {
          circleData = updatedCircleData;
          setState(() {
            allowNameEditing = false;
          });
        }, onError: (error) {
          buildSnackbar(context, 'Error renaming circle: $error');
        });
      } else {
        circleTextController.text = circleData.name;
      }
    }
    processingUpdate = false;
  }

  Future<void> deleteCircle(ConnectionsManager manager) async {
    final confirm = await showYesNoDialog(context,
        "Permanently delete circle ${circleData.name}? This can't be undone.");
    if (context.mounted && confirm == true) {
      await manager.deleteCircle(circleData).match(
            onSuccess: (_) => context.canPop() ? context.pop() : null,
            onError: (error) =>
                buildSnackbar(context, 'Error trying to delete circle: $error'),
          );
    }
  }

  Future<void> removeUserFromCircle(
    ConnectionsManager manager,
    Connection connection,
  ) async {
    final messageBase = '${connection.name} from ${circleData.name}';
    final confirm = await showYesNoDialog(context, 'Remove $messageBase?');
    if (context.mounted && confirm == true) {
      final message =
          await manager.removeUserFromCircle(circleData, connection).fold(
                onSuccess: (_) => 'Removed $messageBase',
                onError: (error) => 'Error removing $messageBase: $error',
              );
      buildSnackbar(context, message);
    }
  }

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

  @override
  Widget build(BuildContext context) {
    final nss = getIt<NetworkStatusService>();
    final manager = context
        .watch<ActiveProfileSelector<ConnectionsManager>>()
        .activeEntry
        .value;

    final filterTextLC = filterText.toLowerCase();
    final members = manager
        .getCircleMembers(circleData)
        .transform((ms) => ms
            .where((m) =>
                filterText.isEmpty ||
                m.name.toLowerCase().contains(filterTextLC) ||
                m.handle.toLowerCase().contains(filterTextLC))
            .toList())
        .getValueOrElse(() => <Connection>[]);

    return Scaffold(
        appBar: StandardAppBar.build(
          context,
          'Circle Editor',
          withHome: false,
          actions: [
            IconButton(
              onPressed: () => deleteCircle(manager),
              icon: const Icon(Icons.delete),
            ),
          ],
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: RefreshIndicator(
            onRefresh: () async {
              manager.refreshCircles();
            },
            child: ResponsiveMaxWidth(
              child: Column(
                children: [
                  StandardLinearProgressIndicator(nss.connectionUpdateStatus),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Row(
                      children: [
                        Expanded(
                          child: TextFormField(
                            enabled: allowNameEditing,
                            readOnly: !allowNameEditing,
                            onEditingComplete: () async {
                              if (processingUpdate) {
                                return;
                              }
                              updateCircleName(context, manager);
                            },
                            onTapOutside: (_) async {
                              if (processingUpdate) {
                                return;
                              }
                              updateCircleName(context, manager);
                            },
                            controller: circleTextController,
                            textCapitalization: TextCapitalization.sentences,
                            decoration: InputDecoration(
                              labelText: 'Circle Name',
                              border: OutlineInputBorder(
                                borderSide: const BorderSide(),
                                borderRadius: BorderRadius.circular(5.0),
                              ),
                            ),
                          ),
                        ),
                        const HorizontalPadding(),
                        IconButton(
                          onPressed: () {
                            if (allowNameEditing) {
                              circleTextController.text = circleData.name;
                            }
                            setState(() {
                              allowNameEditing = !allowNameEditing;
                            });
                          },
                          icon: const Icon(Icons.edit),
                        ),
                      ],
                    ),
                  ),
                  const VerticalPadding(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text('Circle Members:',
                          style: Theme.of(context).textTheme.headlineSmall),
                      IconButton(
                          onPressed: () {
                            context.push(
                                '${ScreenPaths.circleManagement}/add_users/${widget.circleId}');
                          },
                          icon: const Icon(Icons.add)),
                    ],
                  ),
                  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),
                        ),
                      )
                    ],
                  ),
                  Expanded(
                    child: ListView.separated(
                      physics: const AlwaysScrollableScrollPhysics(),
                      itemBuilder: (context, index) {
                        final m = members[index];
                        return ListTile(
                          onTap: () {
                            context.pushNamed(ScreenPaths.userProfile,
                                pathParameters: {'id': m.id});
                          },
                          title: Text(
                            '${m.name} (${m.handle})',
                            softWrap: true,
                          ),
                          subtitle: Text(
                            'Last Status: ${m.lastStatus?.toIso8601String() ?? "Unknown"}',
                            softWrap: true,
                          ),
                          trailing: IconButton(
                            onPressed: () async =>
                                removeUserFromCircle(manager, m),
                            icon: const Icon(Icons.remove),
                          ),
                        );
                      },
                      separatorBuilder: (_, __) => const Divider(),
                      itemCount: members.length,
                    ),
                  ),
                ],
              ),
            ),
          ),
        ));
  }
}
