import 'package:flutter/material.dart';

import '../../../../api/errors/error_mapper.dart';
import '../../../../api/marianumcloud/talk/get_poll/get_poll_state.dart';
import '../../../../api/marianumcloud/talk/get_poll/get_poll_state_response.dart';
import '../../../../api/marianumcloud/talk/room/get_room_response.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../../../../widget/loading_spinner.dart';
import 'poll_options_list.dart';

/// Opens the poll bottom sheet for a Talk poll attached to a message. Loads the
/// poll state lazily; voting and closing reload the state in place and refresh
/// the chat so the surrounding message list stays in sync.
void showChatBubblePollSheet(
  BuildContext context, {
  required GetRoomResponseObject room,
  required int pollId,
  required String pollName,
  required void Function({bool renew}) refetch,
}) {
  showDetailsBottomSheet(
    context,
    header: ListTile(
      leading: const Icon(Icons.poll_outlined),
      title: Text(pollName, overflow: TextOverflow.ellipsis),
      subtitle: const Text('Umfrage'),
    ),
    children: (sheetCtx) => [
      const SizedBox(height: 8),
      _PollSheetBody(room: room, pollId: pollId, refetch: refetch),
      const SizedBox(height: 16),
    ],
  );
}

class _PollSheetBody extends StatefulWidget {
  final GetRoomResponseObject room;
  final int pollId;
  final void Function({bool renew}) refetch;

  const _PollSheetBody({
    required this.room,
    required this.pollId,
    required this.refetch,
  });

  @override
  State<_PollSheetBody> createState() => _PollSheetBodyState();
}

class _PollSheetBodyState extends State<_PollSheetBody> {
  Future<GetPollStateResponse>? _future;

  @override
  void initState() {
    super.initState();
    _future = GetPollState(token: widget.room.token, pollId: widget.pollId).run();
  }

  void _reload() {
    setState(() {
      _future = GetPollState(
        token: widget.room.token,
        pollId: widget.pollId,
      ).run();
    });
  }

  void _applyState(GetPollStateResponse state) {
    setState(() {
      // Block body: an arrow would return the Future, which setState rejects.
      _future = Future.value(state);
    });
    widget.refetch(renew: true);
  }

  @override
  Widget build(BuildContext context) => FutureBuilder<GetPollStateResponse>(
    future: _future,
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        return const Padding(
          padding: EdgeInsets.all(24),
          child: LoadingSpinner(),
        );
      }
      if (snapshot.hasError) {
        return Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            children: [
              Text(
                errorToUserMessage(snapshot.error),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 12),
              FilledButton.tonal(
                onPressed: _reload,
                child: const Text('Erneut versuchen'),
              ),
            ],
          ),
        );
      }
      return PollOptionsList(
        pollData: snapshot.data!.data,
        room: widget.room,
        onStateChanged: _applyState,
      );
    },
  );
}
