import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/common/widgets/search_bar.dart';
import 'package:syncrow_web/common/widgets/sidebar_communities_list.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_event.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_tile.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/sidebar_header.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_tile_widget.dart';
import 'package:syncrow_web/pages/spaces_management/create_community/view/create_community_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_event.dart';
import 'package:syncrow_web/utils/style.dart';

import '../../../space_tree/bloc/space_tree_event.dart';

class SidebarWidget extends StatefulWidget {
  final List<CommunityModel> communities;
  final String? selectedSpaceUuid;
  final void Function(String name, String description) onCreateCommunity;

  const SidebarWidget({
    required this.communities,
    required this.onCreateCommunity,
    this.selectedSpaceUuid,
    super.key,
  });

  @override
  State<SidebarWidget> createState() => _SidebarWidgetState();
}

class _SidebarWidgetState extends State<SidebarWidget> {
  late final ScrollController _scrollController;
  Timer? _debounce;

  String _searchQuery = '';
  String? _selectedSpaceUuid;
  String? _selectedId;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController();
    _scrollController.addListener(_onScroll);
    _selectedId = widget.selectedSpaceUuid;
    _searchQuery = '';
    context.read<SpaceTreeBloc>().add(ClearCachedData());
  }

  void _onScroll() {
    if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 100) {
      // Trigger pagination event
      final bloc = context.read<SpaceTreeBloc>();
      if (!bloc.state.paginationIsLoading && bloc.state.paginationModel?.hasNext == true) {
        bloc.add(
          PaginationEvent(
            bloc.state.paginationModel!,
            bloc.state.communityList,
          ),
        );
      }
    }
  }

  @override
  void dispose() {
    _scrollController.removeListener(_onScroll);
    _scrollController.dispose();
    _debounce?.cancel();
    super.dispose();
  }

  void _onSearchChanged(String query) {
    if (_debounce?.isActive ?? false) _debounce?.cancel();

    _debounce = Timer(const Duration(milliseconds: 500), () {
      setState(() {
        _searchQuery = query;
      });
      context.read<SpaceTreeBloc>().add(SearchQueryEvent(query));
    });
  }

  @override
  void didUpdateWidget(covariant SidebarWidget oldWidget) {
    if (widget.selectedSpaceUuid != oldWidget.selectedSpaceUuid) {
      setState(() => _selectedId = widget.selectedSpaceUuid);
    }
    super.didUpdateWidget(oldWidget);
  }

  bool _isSpaceOrChildSelected(SpaceModel space) {
    final isSpaceSelected = _selectedSpaceUuid == space.uuid;
    final anySubSpaceIsSelected = space.children.any(_isSpaceOrChildSelected);
    return isSpaceSelected || anySubSpaceIsSelected;
  }

  static const _width = 300.0;

  @override
  Widget build(BuildContext context) {
    final spaceTreeState = context.watch<SpaceTreeBloc>().state;
    final filteredCommunities = spaceTreeState.searchQuery.isNotEmpty
        ? spaceTreeState.filteredCommunity
        : spaceTreeState.communityList;

    return Container(
      width: _width,
      decoration: subSectionContainerDecoration,
      child: spaceTreeState is SpaceTreeLoadingState
          ? const Center(child: CircularProgressIndicator())
          : Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                SidebarHeader(onAddCommunity: _onAddCommunity),
                CustomSearchBar(
                  onSearchChanged: _onSearchChanged,
                ),
                const SizedBox(height: 16),
                Expanded(
                  child: Builder(
                    builder: (_) {
                      return SidebarCommunitiesList(
                        scrollController: _scrollController,
                        onScrollToEnd: () {},
                        communities: filteredCommunities,
                        itemBuilder: (context, index) {
                          if (index == filteredCommunities.length) {
                            final spaceTreeState = context.read<SpaceTreeBloc>().state;
                            if (spaceTreeState.paginationIsLoading) {
                              return const Padding(
                                padding: EdgeInsets.all(8.0),
                                child: Center(child: CircularProgressIndicator()),
                              );
                            } else {
                              return const SizedBox.shrink();
                            }
                          }
                          return _buildCommunityTile(context, filteredCommunities[index]);
                        },
                      );
                    },
                  ),
                ),
                if (spaceTreeState.paginationIsLoading || spaceTreeState.isSearching)
                  Center(
                    child: CircularProgressIndicator(),
                  )
              ],
            ),
    );
  }

  Widget _buildCommunityTile(BuildContext context, CommunityModel community) {
    final spaces = community.spaces
        .where(
          (space) =>
              {
                SpaceStatus.deleted,
                SpaceStatus.parentDeleted,
              }.contains(space.status) ==
              false,
        )
        .map((space) => _buildSpaceTile(space: space, community: community))
        .toList();
    return CommunityTile(
      title: community.name,
      key: ValueKey(community.uuid),
      isSelected: _selectedId == community.uuid,
      isExpanded: false,
      onItemSelected: () {
        setState(() {
          _selectedId = community.uuid;
          _selectedSpaceUuid = null;
        });

        context.read<CenterBodyBloc>().add(CommunitySelectedEvent());

        context.read<SpaceManagementBloc>().add(
              SelectCommunityEvent(selectedCommunity: community),
            );
      },
      onExpansionChanged: (title, expanded) {},
      children: spaces,
    );
  }

  Widget _buildSpaceTile({
    required SpaceModel space,
    required CommunityModel community,
  }) {
    final spaceIsExpanded = _isSpaceOrChildSelected(space);
    final isSelected = _selectedId == space.uuid;
    return Padding(
      padding: const EdgeInsetsDirectional.only(start: 16.0),
      child: SpaceTile(
        title: space.name,
        key: ValueKey(space.uuid),
        isSelected: isSelected,
        initiallyExpanded: spaceIsExpanded,
        onExpansionChanged: (expanded) {},
        onItemSelected: () {
          setState(() {
            _selectedId = space.uuid;
            _selectedSpaceUuid = space.uuid;
          });

          context.read<SpaceManagementBloc>().add(
                SelectSpaceEvent(selectedCommunity: community, selectedSpace: space),
              );
        },
        children: space.children
            .map(
              (childSpace) => _buildSpaceTile(
                space: childSpace,
                community: community,
              ),
            )
            .toList(),
      ),
    );
  }

  void _onAddCommunity() =>
      _selectedId?.isNotEmpty ?? true ? _clearSelection() : _showCreateCommunityDialog();

  void _clearSelection() {
    setState(() => _selectedId = '');
    context.read<SpaceManagementBloc>().add(
          NewCommunityEvent(communities: widget.communities),
        );
  }

  void _showCreateCommunityDialog() {
    showDialog<void>(
      context: context,
      builder: (context) => CreateCommunityDialog(
        isEditMode: false,
        existingCommunityNames: widget.communities.map((e) => e.name).toList(),
        onCreateCommunity: widget.onCreateCommunity,
      ),
    );
  }
}
