import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:easy_refresh/easy_refresh.dart';
import '../../core/theme/app_colors_extension.dart';
import '../../shared/widgets/nav_bar_config.dart';
import '../../core/utils/date_utils.dart' as du;
import '../../core/utils/responsive.dart';
import '../../shared/widgets/empty_state.dart';
import '../../shared/widgets/skeleton_list_card.dart';
import '../../shared/widgets/list_footer.dart';
import '../../core/i18n/app_localizations.dart';
import '../../core/auth/role_provider.dart';
import 'announcement_list_controller.dart';
import 'announcement_model.dart';

class AnnouncementListPage extends ConsumerStatefulWidget {
  const AnnouncementListPage({super.key});
  @override
  ConsumerState<AnnouncementListPage> createState() =>
      _AnnouncementListPageState();
}

class _AnnouncementListPageState extends ConsumerState<AnnouncementListPage>
    with TickerProviderStateMixin {
  late TabController _tabCtrl;

  static List<String> _getTabLabels(bool isAdmin, AppLocalizations l10n) =>
      isAdmin
      ? [
          l10n.get('all'),
          l10n.get('noticeAnnouncement'),
          l10n.get('hrPolicy'),
          l10n.get('holidayActivity'),
          l10n.get('draft'),
        ]
      : [
          l10n.get('all'),
          l10n.get('noticeAnnouncement'),
          l10n.get('hrPolicy'),
          l10n.get('holidayActivity'),
        ];

  @override
  void initState() {
    super.initState();
    final isAdmin = ref.read(isAdminProvider);
    _tabCtrl = TabController(length: isAdmin ? 5 : 4, vsync: this);
    _tabCtrl.addListener(_onTabChanged);
  }

  void _onTabChanged() {
    if (!_tabCtrl.indexIsChanging) {
      ref.read(announcementTabProvider.notifier).state = _tabCtrl.index;
    }
  }

  @override
  void dispose() {
    _tabCtrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final isAdmin = ref.watch(isAdminProvider);
    final l10n = AppLocalizations.of(context);
    final tabs = _getTabLabels(isAdmin, l10n);
    final tabIndex = ref.watch(announcementTabProvider);
    final r = ResponsiveHelper.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;

    // Handle TabController recreation when tab count changes (isAdmin toggle)
    if (_tabCtrl.length != tabs.length) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (!mounted) return;
        final newIdx = tabIndex >= tabs.length ? 0 : tabIndex;
        _tabCtrl.dispose();
        _tabCtrl = TabController(
          length: tabs.length,
          vsync: this,
          initialIndex: newIdx,
        );
        _tabCtrl.addListener(_onTabChanged);
        setState(() {});
      });
      // Render a simplified view during this frame to avoid length mismatch
      return Center(
        child: ConstrainedBox(
          constraints: BoxConstraints(maxWidth: r.listMaxWidth),
          child: Column(
            children: [
              Container(
                color: colors.bgCard,
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: TDTabBar(
                  tabs: tabs.map((l) => TDTab(text: l)).toList(),
                  isScrollable: true,
                  labelColor: colors.primary,
                  unselectedLabelColor: colors.textSecondary,
                  outlineType: TDTabBarOutlineType.filled,
                  showIndicator: true,
                  indicatorColor: colors.primary,
                  indicatorHeight: 3,
                  dividerHeight: 0,
                  labelPadding: const EdgeInsets.symmetric(horizontal: 12),
                ),
              ),
              const Expanded(child: SizedBox.shrink()),
            ],
          ),
        ),
      );
    }

    // Sync TabController with external changes
    if (_tabCtrl.index != tabIndex && !_tabCtrl.indexIsChanging) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted) _tabCtrl.animateTo(tabIndex);
      });
    }

    setNavBarTitle(context, ref, NavBarConfig(
      title: l10n.get('announcementList'),
      showBack: true,
      onBack: () => context.pop(),
    ));
    return Center(
      child: ConstrainedBox(
        constraints: BoxConstraints(maxWidth: r.listMaxWidth),
        child: Column(
          children: [
            Container(
              color: colors.bgCard,
              padding: EdgeInsets.zero,
              child: TDSearchBar(
                placeHolder: l10n.get('searchAnnouncement'),
                needCancel: true,
                style: TDSearchStyle.round,
              ),
            ),
            Container(
              color: colors.bgCard,
              padding: const EdgeInsets.symmetric(horizontal: 8),
              child: TDTabBar(
                tabs: tabs.map((l) => TDTab(text: l)).toList(),
                controller: _tabCtrl,
                isScrollable: true,
                labelColor: colors.primary,
                unselectedLabelColor: colors.textSecondary,
                outlineType: TDTabBarOutlineType.filled,
                showIndicator: true,
                indicatorColor: colors.primary,
                indicatorHeight: 3,
                dividerHeight: 0,
                labelPadding: const EdgeInsets.symmetric(horizontal: 12),
                onTap: (index) {
                  ref.read(announcementTabProvider.notifier).state = index;
                },
              ),
            ),
            Expanded(
              child: Container(
                color: colors.bgPage,
                child: TabBarView(
                  controller: _tabCtrl,
                  children: List.generate(tabs.length, (tabIdx) {
                    return _AnnouncementTabContent(tabIndex: tabIdx);
                  }),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _AnnouncementTabContent extends ConsumerWidget {
  final int tabIndex;

  const _AnnouncementTabContent({required this.tabIndex});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final itemsAsync = ref.watch(filteredAnnouncementsProvider(tabIndex));

    if (itemsAsync.isLoading && !itemsAsync.hasValue) {
      return SkeletonLoadingList(
        cardBuilder: () => const SkeletonAnnouncementCard(),
      );
    }

    return EasyRefresh(
      header: TDRefreshHeader(),
      onRefresh: () async {
        ref.read(announcementRefreshProvider.notifier).state++;
      },
      child: _buildContent(itemsAsync, context, ref),
    );
  }

  Widget _buildContent(
    AsyncValue<List<AnnouncementModel>> itemsAsync,
    BuildContext context,
    WidgetRef ref,
  ) {
    final l10n = AppLocalizations.of(context);
    if (itemsAsync.isReloading) {
      final oldItems = itemsAsync.valueOrNull ?? [];
      if (oldItems.isEmpty) {
        return ListView(
          children: [
            const SizedBox(height: 120),
            EmptyState(message: l10n.get('noAnnouncements')),
          ],
        );
      }
      return ListView.builder(
        padding: const EdgeInsets.symmetric(vertical: 8),
        itemCount: oldItems.length,
        itemBuilder: (_, i) => _buildAnnouncementCard(context, oldItems[i]),
      );
    }

    if (itemsAsync.hasError) {
      return ListView(
        children: [
          const SizedBox(height: 120),
          EmptyState(message: l10n.get('loadFailed')),
        ],
      );
    }

    final items = itemsAsync.requireValue;
    if (items.isEmpty) {
      return ListView(
        children: [
          const SizedBox(height: 120),
          EmptyState(message: l10n.get('noAnnouncements')),
        ],
      );
    }

    return ListView.builder(
      padding: const EdgeInsets.symmetric(vertical: 8),
      itemCount: items.length + 1,
      itemBuilder: (_, i) {
        if (i == items.length) return ListFooter(itemCount: items.length);
        return _buildAnnouncementCard(context, items[i]);
      },
    );
  }

  Widget _buildAnnouncementCard(BuildContext context, AnnouncementModel item) {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final expired = item.isExpired;
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
      child: GestureDetector(
        onTap: () => context.push('/announcement/detail/${item.id}'),
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 200),
          padding: const EdgeInsets.all(12),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(8),
            color: expired ? colors.bgDisabled : colors.bgCard,
          ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 标题行
              Row(
                children: [
                  // 置顶标记
                  if (item.isTop)
                    Container(
                      margin: const EdgeInsets.only(right: 6),
                      padding: const EdgeInsets.symmetric(
                        horizontal: 4,
                        vertical: 1,
                      ),
                      decoration: BoxDecoration(
                        color: colors.danger,
                        borderRadius: BorderRadius.circular(2),
                      ),
                      child: Text(
                        l10n.get('pinTopTag'),
                        style: const TextStyle(
                          fontSize: 10,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  // 标题
                  Expanded(
                    child: Text(
                      item.title,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: TextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.w600,
                        color: expired
                            ? colors.textPlaceholder
                            : colors.textPrimary,
                        decoration: expired ? TextDecoration.lineThrough : null,
                      ),
                    ),
                  ),
                  // 已过期标记
                  if (expired)
                    Container(
                      margin: const EdgeInsets.only(left: 6),
                      padding: const EdgeInsets.symmetric(
                        horizontal: 6,
                        vertical: 2,
                      ),
                      decoration: BoxDecoration(
                        color: colors.bgPage,
                        borderRadius: BorderRadius.circular(3),
                      ),
                      child: Text(
                        l10n.get('expired'),
                        style: TextStyle(
                          fontSize: 10,
                          color: colors.textPlaceholder,
                        ),
                      ),
                    ),
                  // 未读红点
                  if (!item.isRead && !expired)
                    Container(
                      margin: const EdgeInsets.only(left: 6),
                      width: 8,
                      height: 8,
                      decoration: BoxDecoration(
                        color: colors.danger,
                        shape: BoxShape.circle,
                      ),
                    ),
                ],
              ),
              const SizedBox(height: 8),
              // 元信息行
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Row(
                    children: [
                      _buildTypeTag(context, item.typeLabel, l10n),
                      const SizedBox(width: 8),
                      Text(
                        item.publisherName,
                        style: TextStyle(
                          fontSize: 12,
                          color: colors.textSecondary,
                        ),
                      ),
                    ],
                  ),
                  Text(
                    du.DateUtils.formatDateTime(item.publishTime),
                    style: TextStyle(
                      fontSize: 12,
                      color: colors.textPlaceholder,
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTypeTag(
    BuildContext context,
    String type,
    AppLocalizations l10n,
  ) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    Color bgColor;
    Color textColor;
    switch (type) {
      case '人事与制度':
        bgColor = colors.successBg;
        textColor = colors.success;
        break;
      case '放假与活动':
        bgColor = colors.warningBg;
        textColor = colors.warning;
        break;
      default: // 通知公告
        bgColor = colors.primaryLight;
        textColor = colors.primary;
    }
    final displayText = switch (type) {
      '人事与制度' => l10n.get('hrPolicy'),
      '放假与活动' => l10n.get('holidayActivity'),
      _ => l10n.get('noticeAnnouncement'),
    };
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: bgColor,
        borderRadius: BorderRadius.circular(3),
      ),
      child: Text(
        displayText,
        style: TextStyle(fontSize: 11, color: textColor),
      ),
    );
  }
}
