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

import '../controls/image_control.dart';
import '../controls/padding.dart';
import '../controls/responsive_max_width.dart';
import '../controls/standard_appbar.dart';
import '../globals.dart';
import '../models/direct_message_thread.dart';
import '../models/exec_error.dart';
import '../services/auth_service.dart';
import '../services/direct_message_service.dart';
import '../utils/active_profile_selector.dart';
import '../utils/clipboard_utils.dart';
import '../utils/snackbar_builder.dart';

class MessageThreadScreen extends StatefulWidget {
  final String parentThreadId;

  const MessageThreadScreen({
    super.key,
    required this.parentThreadId,
  });

  @override
  State<MessageThreadScreen> createState() => _MessageThreadScreenState();
}

class _MessageThreadScreenState extends State<MessageThreadScreen> {
  final textController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final service = context
        .watch<ActiveProfileSelector<DirectMessageService>>()
        .activeEntry
        .value;
    final result = service.getThreadByParentUri(widget.parentThreadId);
    final title = result.fold(
        onSuccess: (t) => t.title.isEmpty ? 'Thread' : t.title,
        onError: (_) => 'Thread');
    return Scaffold(
      appBar: StandardAppBar.build(context, title),
      body: buildBody(result, service),
    );
  }

  Widget buildBody(
    Result<DirectMessageThread, ExecError> result,
    DirectMessageService service,
  ) {
    return result.fold(
      onSuccess: (thread) {
        final yourId = getIt<AccountsService>().currentProfile.userId;
        final yourAvatarUrl = getIt<AccountsService>().currentProfile.avatar;
        final participants =
            Map.fromEntries(thread.participants.map((p) => MapEntry(p.id, p)));
        return Center(
            child: Column(
          children: [
            Expanded(
              child: ResponsiveMaxWidth(
                child: ListView.separated(
                    itemBuilder: (context, index) {
                      final m = thread.messages[index];
                      final textPieces = m.text.split('...\n');
                      final text = textPieces.length == 1
                          ? textPieces[0]
                          : textPieces[1];
                      final imageUrl = m.senderId == yourId
                          ? yourAvatarUrl
                          : participants[m.senderId]?.avatarUrl ?? '';
                      return ListTile(
                        onTap: m.seen
                            ? null
                            : () => service.markMessageRead(
                                widget.parentThreadId, m),
                        onLongPress: () async {
                          await copyToClipboard(context: context, text: m.text);
                        },
                        leading: ImageControl(
                          imageUrl: imageUrl,
                          iconOverride: const Icon(Icons.person),
                          width: 32.0,
                          onTap: null,
                        ),
                        title: Text(
                          text,
                          style: m.seen
                              ? null
                              : const TextStyle(fontWeight: FontWeight.bold),
                        ),
                        subtitle: Text(DateTime.fromMillisecondsSinceEpoch(
                                m.createdAt * 1000)
                            .toString()),
                      );
                    },
                    separatorBuilder: (_, __) => const Divider(),
                    itemCount: thread.messages.length),
              ),
            ),
            const VerticalDivider(),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: ResponsiveMaxWidth(
                child: TextFormField(
                  controller: textController,
                  maxLines: 4,
                  decoration: InputDecoration(
                    labelText: 'Reply Text',
                    border: OutlineInputBorder(
                      borderSide: BorderSide(
                        color: Theme.of(context).colorScheme.background,
                      ),
                      borderRadius: BorderRadius.circular(5.0),
                    ),
                  ),
                ),
              ),
            ),
            ElevatedButton(
              onPressed: () async {
                if (textController.text.isEmpty) {
                  buildSnackbar(context, "Can't submit an empty reply");
                  return;
                }
                final othersMessages =
                    thread.messages.where((m) => m.senderId != yourId);
                if (othersMessages.isEmpty) {
                  buildSnackbar(
                      context, "Have to wait for a response before sending");
                  return;
                }
                await service
                    .newReplyMessage(
                  thread.parentUri,
                  othersMessages.last,
                  textController.text,
                )
                    .match(onSuccess: (_) {
                  setState(() {
                    textController.clear();
                  });
                }, onError: (error) {
                  if (mounted) {
                    buildSnackbar(context, error.message);
                  }
                });
              },
              child: const Text('Submit'),
            ),
            const VerticalPadding(),
          ],
        ));
      },
      onError: (error) => Center(
        child: Text('Error getting thread: $error'),
      ),
    );
  }
}
