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

import '../controls/html_text_viewer_control.dart';
import '../controls/login_aware_cached_network_image.dart';
import '../controls/padding.dart';
import '../globals.dart';
import '../models/auth/profile.dart';
import '../models/connection.dart';
import '../models/timeline_grouping_list_data.dart';
import '../riverpod_controllers/account_services.dart';
import '../riverpod_controllers/blocks_services.dart';
import '../riverpod_controllers/circles_repo_services.dart';
import '../riverpod_controllers/connection_manager_services.dart';
import '../routes.dart';
import '../utils/snackbar_builder.dart';
import '../utils/url_opening_utils.dart';

class UserProfileScreen extends ConsumerStatefulWidget {
  final String userId;

  const UserProfileScreen({super.key, required this.userId});

  @override
  ConsumerState<UserProfileScreen> createState() => _UserProfileScreenState();
}

class _UserProfileScreenState extends ConsumerState<UserProfileScreen> {
  var isUpdating = false;

  @override
  void initState() {
    super.initState();
    final profile = ref.read(activeProfileProvider);
    ref.read(connectionByIdProvider(profile, widget.userId, forceUpdate: true));
  }

  @override
  Widget build(BuildContext context) {
    final profile = ref.watch(activeProfileProvider);
    ref.watch(blocksManagerProvider(profile));
    final body = ref.watch(connectionByIdProvider(profile, widget.userId)).fold(
        onSuccess: (connectionProfile) {
      final notMyProfile = profile.userId != connectionProfile.id;

      return RefreshIndicator(
        onRefresh: () async {
          await ref
              .read(blocksManagerProvider(profile).notifier)
              .updateBlock(connectionProfile);
          setState(() {});
        },
        child: SingleChildScrollView(
          physics: const AlwaysScrollableScrollPhysics(),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              LoginAwareCachedNetworkImage(
                  imageUrl: connectionProfile.avatarUrl.toString()),
              const Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: [],
              ),
              Text(
                notMyProfile
                    ? '${connectionProfile.name} (${connectionProfile.handle})'
                    : '${connectionProfile.name} (Your Account)',
                softWrap: true,
                textAlign: TextAlign.center,
                style: Theme.of(context).textTheme.titleLarge,
              ),
              const VerticalPadding(),
              if (connectionProfile.status != ConnectionStatus.unknown)
                Text('( ${connectionProfile.status.label()} )'),
              const VerticalPadding(),
              Wrap(
                spacing: 10.0,
                runSpacing: 10.0,
                children: [
                  ElevatedButton(
                    onPressed: () => context.pushNamed(
                      ScreenPaths.userPosts,
                      pathParameters: {'id': connectionProfile.id},
                    ),
                    child: const Text('Posts'),
                  ),
                  ElevatedButton(
                    onPressed: () => context.pushNamed(
                      ScreenPaths.userPostsAndComments,
                      pathParameters: {'id': connectionProfile.id},
                    ),
                    child: const Text('Posts & Comments'),
                  ),
                  ElevatedButton(
                    onPressed: () => context.pushNamed(
                      ScreenPaths.userMedia,
                      pathParameters: {'id': connectionProfile.id},
                    ),
                    child: const Text('Media'),
                  ),
                  ElevatedButton(
                    onPressed: () async =>
                        await openProfileExternal(context, connectionProfile),
                    child: const Text('Open In Browser'),
                  ),
                ],
              ),
              const VerticalPadding(),
              Wrap(
                spacing: 10.0,
                runSpacing: 10.0,
                children: [
                  if (notMyProfile) ...[
                    buildConnectionStatusToggle(
                      context,
                      profile,
                      connectionProfile,
                    ),
                    buildBlockToggle(context, profile, connectionProfile),
                  ],
                ],
              ),
              const VerticalPadding(),
              HtmlTextViewerControl(
                content: connectionProfile.note,
                onTapUrl: (url) async {
                  return await openUrlStringInSystembrowser(
                      context, url, 'link');
                },
              ),
              const VerticalPadding(),
              Text(
                  '#Followers: ${connectionProfile.followerCount} followers, #Following, ${connectionProfile.followingCount}, #Statuses: ${connectionProfile.statusesCount}'),
              const VerticalPadding(),
              Text('Last Status: ${connectionProfile.lastStatus ?? "Unknown"}'),
              const VerticalPadding(),
              if (connectionProfile.status == ConnectionStatus.mutual ||
                  connectionProfile.status == ConnectionStatus.youFollowThem)
                buildCircles(context, profile, connectionProfile),
            ],
          ),
        ),
      );
    }, onError: (error) {
      return Text('Error getting profile: $error');
    });
    return Scaffold(
      appBar: AppBar(
        title: const Text('Profile'),
        leading: context.canPop()
            ? null
            : IconButton(
                onPressed: () => context.go(ScreenPaths.timelines),
                icon: const Icon(Icons.arrow_back),
              ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Center(
          child: body,
        ),
      ),
    );
  }

  Widget buildCircles(
    BuildContext context,
    Profile profile,
    Connection connectionProfile,
  ) {
    final myCircles =
        ref.watch(timelineGroupingListProvider(profile, GroupingType.circle));
    final usersCircles = ref
        .watch(circlesProvider(profile).notifier)
        .getCirclesForUser(connectionProfile.id)
        .fold(
            onSuccess: (circles) => circles.toSet(),
            onError: (error) {
              buildSnackbar(context, 'Error getting circle data: $error');
              return <TimelineGroupingListData>{};
            });
    if (myCircles.isNotEmpty) {
      myCircles.sort((g1, g2) => g1.name.compareTo(g2.name));
    }

    final circlesWidgets = myCircles.map((g) {
      return CheckboxListTile(
        title: Text(g.name),
        value: usersCircles.contains(g),
        onChanged: isUpdating
            ? null
            : (bool? value) async {
                if (isUpdating) {
                  return;
                }

                final isAdding = value == true;
                final confirm = await showYesNoDialog(
                    context,
                    isAdding
                        ? 'Add user to ${g.name}'
                        : 'Remove user from ${g.name}');
                if (confirm != true) {
                  return;
                }
                setState(() {
                  isUpdating = true;
                });
                if (isAdding) {
                  await ref
                      .watch(circlesProvider(profile).notifier)
                      .addConnectionToCircle(g, connectionProfile);
                } else {
                  await ref
                      .watch(circlesProvider(profile).notifier)
                      .removeConnectionFromCircle(g, connectionProfile);
                }
                if (context.mounted) {
                  buildSnackbar(context, "User's Circles Updated");
                }

                setState(() {
                  isUpdating = false;
                });
              },
      );
    }).toList();
    return Column(
      children: [
        Text(
          'Circles: ',
          style: Theme.of(context).textTheme.titleMedium,
        ),
        const VerticalPadding(),
        ...circlesWidgets,
      ],
    );
  }

  Widget buildBlockToggle(
    BuildContext context,
    Profile profile,
    Connection connection,
  ) {
    late Widget blockToggleButton;
    switch (connection.status) {
      case ConnectionStatus.blocked:
        blockToggleButton = ElevatedButton(
          onPressed: isUpdating
              ? null
              : () async {
                  final confirm = await showYesNoDialog(
                      context, 'Unblock ${connection.name}');
                  if (confirm != true) {
                    return;
                  }
                  setState(() {
                    isUpdating = true;
                  });
                  await ref
                      .read(blocksManagerProvider(profile).notifier)
                      .unblockConnection(connection);
                  setState(() {
                    isUpdating = false;
                  });
                },
          child: const Text('Unblock'),
        );
        break;
      case ConnectionStatus.mutual:
      case ConnectionStatus.theyFollowYou:
      case ConnectionStatus.youFollowThem:
      case ConnectionStatus.none:
      case ConnectionStatus.unknown:
        blockToggleButton = ElevatedButton(
          onPressed: isUpdating
              ? null
              : () async {
                  final confirm = await showYesNoDialog(
                      context, 'Block ${connection.name}');
                  if (confirm != true) {
                    return;
                  }
                  setState(() {
                    isUpdating = true;
                  });
                  await ref
                      .read(blocksManagerProvider(profile).notifier)
                      .blockConnection(connection);
                  setState(() {
                    isUpdating = false;
                  });
                },
          child: const Text('Block'),
        );
        break;
      case ConnectionStatus.you:
        blockToggleButton = const SizedBox();
        break;
    }
    return blockToggleButton;
  }

  Widget buildConnectionStatusToggle(
    BuildContext context,
    Profile profile,
    Connection connectionProfile,
  ) {
    late Widget followToggleButton;
    switch (connectionProfile.status) {
      case ConnectionStatus.mutual:
      case ConnectionStatus.youFollowThem:
        followToggleButton = ElevatedButton(
          onPressed: isUpdating
              ? null
              : () async {
                  final confirm = await showYesNoDialog(
                      context, 'Unfollow ${connectionProfile.name}');
                  if (confirm != true) {
                    return;
                  }
                  setState(() {
                    isUpdating = true;
                  });
                  await ref
                      .read(
                          connectionModifierProvider(profile, connectionProfile)
                              .notifier)
                      .unfollow();
                  setState(() {
                    isUpdating = false;
                  });
                },
          child: const Text('Unfollow'),
        );
        break;
      case ConnectionStatus.theyFollowYou:
      case ConnectionStatus.none:
        followToggleButton = ElevatedButton(
          onPressed: isUpdating
              ? null
              : () async {
                  final confirm = await showYesNoDialog(
                      context, 'Follow ${connectionProfile.name}');
                  if (confirm != true) {
                    return;
                  }
                  setState(() {
                    isUpdating = true;
                  });
                  await ref
                      .read(
                          connectionModifierProvider(profile, connectionProfile)
                              .notifier)
                      .follow();
                  setState(() {
                    isUpdating = false;
                  });
                },
          child: const Text('Follow'),
        );
        break;
      case ConnectionStatus.blocked:
      case ConnectionStatus.you:
      case ConnectionStatus.unknown:
        followToggleButton = const SizedBox();
        break;
    }
    return followToggleButton;
  }
}