import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/custom_icon.dart';
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
import 'package:PiliPlus/common/widgets/dynamic_sliver_appbar_medium.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/pair.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models_new/dynamic/dyn_topic_feed/item.dart';
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/top_details.dart';
import 'package:PiliPlus/pages/dynamics/widgets/dynamic_panel.dart';
import 'package:PiliPlus/pages/dynamics_create/view.dart';
import 'package:PiliPlus/pages/dynamics_tab/view.dart';
import 'package:PiliPlus/pages/dynamics_topic/controller.dart';
import 'package:PiliPlus/utils/global_data.dart';
import 'package:PiliPlus/utils/grid.dart';
import 'package:PiliPlus/utils/num_util.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:waterfall_flow/waterfall_flow.dart';

class DynTopicPage extends StatefulWidget {
  const DynTopicPage({super.key});

  @override
  State<DynTopicPage> createState() => _DynTopicPageState();
}

class _DynTopicPageState extends State<DynTopicPage> {
  final DynTopicController _controller =
      Get.put(DynTopicController(), tag: Utils.generateRandomString(8));

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    return Scaffold(
      resizeToAvoidBottomInset: false,
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {
          if (_controller.accountService.isLogin.value) {
            CreateDynPanel.onCreateDyn(
              context,
              topic: Pair(
                first: int.parse(_controller.topicId),
                second: _controller.topicName,
              ),
            );
          } else {
            SmartDialog.showToast('账号未登录');
          }
        },
        icon: const Icon(CustomIcon.topic_tag, size: 20),
        label: const Text('参与话题'),
      ),
      body: SafeArea(
        top: false,
        bottom: false,
        child: refreshIndicator(
          onRefresh: _controller.onRefresh,
          child: CustomScrollView(
            controller: _controller.scrollController,
            physics: const AlwaysScrollableScrollPhysics(),
            slivers: [
              Obx(() => _buildAppBar(theme, _controller.topState.value)),
              Obx(() {
                if (_controller.topicSortByConf.value?.allSortBy?.isNotEmpty ==
                    true) {
                  return SliverPersistentHeader(
                    pinned: true,
                    delegate: CustomSliverPersistentHeaderDelegate(
                      extent: 30,
                      bgColor: theme.colorScheme.surface,
                      child: SizedBox(
                        height: 30,
                        child: Builder(
                          builder: (context) {
                            return Padding(
                              padding:
                                  const EdgeInsets.only(left: 12, bottom: 6),
                              child: ToggleButtons(
                                fillColor: theme.colorScheme.secondaryContainer,
                                selectedColor:
                                    theme.colorScheme.onSecondaryContainer,
                                constraints: const BoxConstraints(
                                    minWidth: 54, minHeight: 24),
                                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                                borderRadius:
                                    const BorderRadius.all(Radius.circular(25)),
                                onPressed: (index) {
                                  _controller.onSort(_controller.topicSortByConf
                                      .value!.allSortBy![index].sortBy!);
                                  (context as Element).markNeedsBuild();
                                },
                                isSelected: _controller
                                    .topicSortByConf.value!.allSortBy!
                                    .map((e) {
                                  return e.sortBy == _controller.sortBy;
                                }).toList(),
                                children: _controller
                                    .topicSortByConf.value!.allSortBy!
                                    .map((e) {
                                  return Text(
                                    e.sortName!,
                                    style: const TextStyle(
                                      fontSize: 13,
                                      height: 1,
                                    ),
                                    strutStyle: const StrutStyle(
                                      height: 1,
                                      leading: 0,
                                      fontSize: 13,
                                    ),
                                    textScaler: TextScaler.noScaling,
                                  );
                                }).toList(),
                              ),
                            );
                          },
                        ),
                      ),
                    ),
                  );
                }
                return const SliverToBoxAdapter();
              }),
              SliverPadding(
                padding: EdgeInsets.only(
                  bottom: MediaQuery.paddingOf(context).bottom + 80,
                ),
                sliver: Obx(() => _buildBody(_controller.loadingState.value)),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildAppBar(ThemeData theme, LoadingState<TopDetails?> topState) {
    late final paddingTop = MediaQuery.paddingOf(context).top;
    return switch (topState) {
      Loading() => const SliverAppBar(),
      Success(:var response) when (topState.dataOrNull != null) =>
        DynamicSliverAppBarMedium(
          pinned: true,
          callback: (value) => _controller.appbarOffset =
              value - kToolbarHeight - paddingTop - 7,
          title: IgnorePointer(child: Text(response!.topicItem!.name)),
          flexibleSpace: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                image: Image.asset(
                  'assets/images/topic-header-bg.png',
                ).image,
                filterQuality: FilterQuality.low,
                fit: BoxFit.cover,
              ),
            ),
            padding: EdgeInsets.only(
              top: paddingTop,
              left: 12,
              right: 12,
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  height: kToolbarHeight,
                  alignment: Alignment.centerLeft,
                  margin: const EdgeInsets.only(left: 45, right: 78),
                  child: GestureDetector(
                    behavior: HitTestBehavior.opaque,
                    onTap: () => Get.toNamed(
                        '/member?mid=${response.topicCreator!.uid}'),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        NetworkImgLayer(
                          width: 28,
                          height: 28,
                          src: response.topicCreator!.face!,
                          type: ImageType.avatar,
                        ),
                        const SizedBox(width: 10),
                        Flexible(
                          child: Text(
                            response.topicCreator!.name!,
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                        Text(
                          ' 发起',
                          style: TextStyle(color: theme.colorScheme.outline),
                        ),
                      ],
                    ),
                  ),
                ),
                Text(
                  response.topicItem!.name,
                  style: const TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                const SizedBox(height: 6),
                SelectableText(
                  response.topicItem!.description!,
                  style: TextStyle(color: theme.colorScheme.onSurfaceVariant),
                ),
                const SizedBox(height: 10),
                Row(
                  children: [
                    Text(
                      '${NumUtil.numFormat(response.topicItem!.view)}浏览 · ${NumUtil.numFormat(response.topicItem!.discuss)}讨论',
                      style: TextStyle(
                        fontSize: 13,
                        color: theme.colorScheme.outline,
                      ),
                    ),
                    const Spacer(),
                    OutlinedButton.icon(
                      style: OutlinedButton.styleFrom(
                        side: BorderSide(
                          width: 1,
                          color:
                              theme.colorScheme.outline.withValues(alpha: 0.2),
                        ),
                        foregroundColor: _controller.isLike.value == true
                            ? null
                            : theme.colorScheme.onSurfaceVariant,
                        padding: const EdgeInsets.symmetric(horizontal: 10),
                        visualDensity:
                            const VisualDensity(horizontal: -4, vertical: -4),
                        tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      ),
                      onPressed: _controller.onLike,
                      icon: _controller.isLike.value == true
                          ? const Icon(FontAwesomeIcons.solidThumbsUp, size: 13)
                          : const Icon(FontAwesomeIcons.thumbsUp, size: 13),
                      label: Text(
                        NumUtil.numFormat(response.topicItem!.like),
                        style: const TextStyle(fontSize: 13),
                        textScaler: TextScaler.noScaling,
                      ),
                    ),
                    const SizedBox(width: 10),
                    OutlinedButton.icon(
                      style: OutlinedButton.styleFrom(
                        side: BorderSide(
                          width: 1,
                          color:
                              theme.colorScheme.outline.withValues(alpha: 0.2),
                        ),
                        foregroundColor: _controller.isFav.value == true
                            ? null
                            : theme.colorScheme.onSurfaceVariant,
                        padding: const EdgeInsets.symmetric(horizontal: 10),
                        visualDensity:
                            const VisualDensity(horizontal: -4, vertical: -4),
                        tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      ),
                      onPressed: _controller.onFav,
                      icon: _controller.isFav.value == true
                          ? const Icon(FontAwesomeIcons.solidStar, size: 13)
                          : const Icon(FontAwesomeIcons.star, size: 13),
                      label: Text(
                        NumUtil.numFormat(response.topicItem!.fav),
                        style: const TextStyle(fontSize: 13),
                        textScaler: TextScaler.noScaling,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 6),
              ],
            ),
          ),
          actions: [
            IconButton(
              onPressed: () => Utils.shareText(
                  '${_controller.topicName} https://m.bilibili.com/topic-detail?topic_id=${_controller.topicId}')
              // https://www.bilibili.com/v/topic/detail?topic_id=${_controller.topicId}
              ,
              icon: const Icon(MdiIcons.share),
            ),
            PopupMenuButton(
              itemBuilder: (context) {
                return [
                  PopupMenuItem(
                    onTap: _controller.onFav,
                    child: Text(
                        '${_controller.isFav.value == true ? '取消' : ''}收藏'),
                  ),
                  PopupMenuItem(
                    child: const Text('举报'),
                    onTap: () {
                      if (!_controller.accountService.isLogin.value) {
                        SmartDialog.showToast('账号未登录');
                        return;
                      }
                      final isDark = Get.isDarkMode;
                      PageUtils.inAppWebview(
                          'https://www.bilibili.com/h5/topic-active/topic-report?topic_id=${_controller.topicId}&topic_name=${_controller.topicName}&native.theme=${isDark ? 2 : 1}&night=${isDark ? 1 : 0}');
                    },
                  ),
                ];
              },
            ),
            const SizedBox(width: 4),
          ],
        ),
      _ => SliverAppBar(
          pinned: true,
          title: Text(_controller.topicName),
        ),
    };
  }

  Widget _buildBody(LoadingState<List<TopicCardItem>?> loadingState) {
    return switch (loadingState) {
      Loading() =>
        DynamicsTabPage.dynSkeleton(GlobalData().dynamicsWaterfallFlow),
      Success(:var response) => response?.isNotEmpty == true
          ? GlobalData().dynamicsWaterfallFlow
              ? SliverWaterfallFlow.extent(
                  maxCrossAxisExtent: Grid.smallCardWidth * 2,
                  crossAxisSpacing: StyleString.cardSpace / 2,
                  lastChildLayoutTypeBuilder: (index) {
                    if (index == response.length - 1) {
                      _controller.onLoadMore();
                    }
                    return index == response.length
                        ? LastChildLayoutType.foot
                        : LastChildLayoutType.none;
                  },
                  children: [
                    for (var item in response!)
                      if (item.dynamicCardItem != null)
                        DynamicPanel(item: item.dynamicCardItem!)
                      else
                        Text(item.topicType ?? 'err'),
                  ],
                )
              : SliverCrossAxisGroup(
                  slivers: [
                    const SliverFillRemaining(),
                    SliverConstrainedCrossAxis(
                      maxExtent: Grid.smallCardWidth * 2,
                      sliver: SliverList.builder(
                        itemBuilder: (context, index) {
                          if (index == response.length - 1) {
                            _controller.onLoadMore();
                          }
                          final item = response[index];
                          if (item.dynamicCardItem != null) {
                            return DynamicPanel(
                              item: item.dynamicCardItem!,
                            );
                          } else {
                            return Text(item.topicType ?? 'err');
                          }
                        },
                        itemCount: response!.length,
                      ),
                    ),
                    const SliverFillRemaining(),
                  ],
                )
          : HttpError(
              onReload: _controller.onReload,
            ),
      Error(:var errMsg) => HttpError(
          errMsg: errMsg,
          onReload: _controller.onReload,
        ),
    };
  }
}
