import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:open_filex/open_filex.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/core/translation/error_code_localization_mapper.dart';
import 'package:paperless_mobile/core/widgets/material/colored_tab_bar.dart';
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
import 'package:paperless_mobile/features/document_details/view/widgets/document_content_widget.dart';
import 'package:paperless_mobile/features/document_details/view/widgets/document_download_button.dart';
import 'package:paperless_mobile/features/document_details/view/widgets/document_meta_data_widget.dart';
import 'package:paperless_mobile/features/document_details/view/widgets/document_overview_widget.dart';
import 'package:paperless_mobile/features/document_details/view/widgets/document_share_button.dart';
import 'package:paperless_mobile/features/documents/view/widgets/delete_document_confirmation_dialog.dart';
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
import 'package:paperless_mobile/features/similar_documents/cubit/similar_documents_cubit.dart';
import 'package:paperless_mobile/features/similar_documents/view/similar_documents_view.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/connectivity_aware_action_wrapper.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routing/routes/documents_route.dart';
import 'package:paperless_mobile/routing/routes/shells/authenticated_route.dart';
import 'package:paperless_mobile/theme.dart';

class DocumentDetailsPage extends StatefulWidget {
  final int id;
  final String? title;
  final bool isLabelClickable;
  final String? titleAndContentQueryString;
  final String? thumbnailUrl;
  final String? heroTag;

  const DocumentDetailsPage({
    Key? key,
    this.isLabelClickable = true,
    this.titleAndContentQueryString,
    this.thumbnailUrl,
    required this.id,
    this.heroTag,
    this.title,
  }) : super(key: key);

  @override
  State<DocumentDetailsPage> createState() => _DocumentDetailsPageState();
}

class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
  static const double _itemSpacing = 24;

  final _pagingScrollController = ScrollController();
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    initializeDateFormatting(Localizations.localeOf(context).toString());
  }

  @override
  Widget build(BuildContext context) {
    final hasMultiUserSupport =
        context.watch<LocalUserAccount>().hasMultiUserSupport;
    final tabLength = 4 + (hasMultiUserSupport && false ? 1 : 0);
    return AnnotatedRegion(
      value: buildOverlayStyle(
        Theme.of(context),
        systemNavigationBarColor: Theme.of(context).bottomAppBarTheme.color,
      ),
      child: BlocBuilder<DocumentDetailsCubit, DocumentDetailsState>(
        builder: (context, state) {
          return DefaultTabController(
            length: tabLength,
            child: Scaffold(
              extendBodyBehindAppBar: false,
              floatingActionButtonLocation:
                  FloatingActionButtonLocation.endDocked,
              floatingActionButton: switch (state) {
                DocumentDetailsLoaded(document: var document) =>
                  _buildEditButton(document),
                _ => null
              },
              bottomNavigationBar: _buildBottomAppBar(),
              body: NestedScrollView(
                headerSliverBuilder: (context, innerBoxIsScrolled) => [
                  SliverOverlapAbsorber(
                    handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
                        context),
                    sliver:
                        BlocBuilder<DocumentDetailsCubit, DocumentDetailsState>(
                      builder: (context, state) {
                        final title = switch (state) {
                          DocumentDetailsLoaded(document: var document) =>
                            document.title,
                          _ => widget.title ?? '',
                        };
                        return SliverAppBar(
                          title: Text(title),
                          leading: const BackButton(),
                          pinned: true,
                          forceElevated: innerBoxIsScrolled,
                          collapsedHeight: kToolbarHeight,
                          expandedHeight: 250.0,
                          flexibleSpace: FlexibleSpaceBar(
                            background: Builder(
                              builder: (context) {
                                return Hero(
                                  tag: widget.heroTag ?? "thumb_${widget.id}",
                                  child: GestureDetector(
                                    onTap: () {
                                      DocumentPreviewRoute(
                                        id: widget.id,
                                        title: title,
                                      ).push(context);
                                    },
                                    child: Stack(
                                      alignment: Alignment.topCenter,
                                      children: [
                                        Positioned.fill(
                                          child: DocumentPreview(
                                            documentId: widget.id,
                                            title: title,
                                            enableHero: false,
                                            fit: BoxFit.cover,
                                            alignment: Alignment.topCenter,
                                          ),
                                        ),
                                        Positioned.fill(
                                          child: DecoratedBox(
                                            decoration: BoxDecoration(
                                              gradient: LinearGradient(
                                                stops: [0.2, 0.4],
                                                colors: [
                                                  Theme.of(context)
                                                      .colorScheme
                                                      .background
                                                      .withOpacity(0.6),
                                                  Theme.of(context)
                                                      .colorScheme
                                                      .background
                                                      .withOpacity(0.3),
                                                ],
                                                begin: Alignment.topCenter,
                                                end: Alignment.bottomCenter,
                                              ),
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                );
                              },
                            ),
                          ),
                          bottom: ColoredTabBar(
                            tabBar: TabBar(
                              isScrollable: true,
                              tabs: [
                                Tab(
                                  child: Text(
                                    S.of(context)!.overview,
                                    style: TextStyle(
                                      color: Theme.of(context)
                                          .colorScheme
                                          .onPrimaryContainer,
                                    ),
                                  ),
                                ),
                                Tab(
                                  child: Text(
                                    S.of(context)!.content,
                                    style: TextStyle(
                                      color: Theme.of(context)
                                          .colorScheme
                                          .onPrimaryContainer,
                                    ),
                                  ),
                                ),
                                Tab(
                                  child: Text(
                                    S.of(context)!.metaData,
                                    style: TextStyle(
                                      color: Theme.of(context)
                                          .colorScheme
                                          .onPrimaryContainer,
                                    ),
                                  ),
                                ),
                                Tab(
                                  child: Text(
                                    S.of(context)!.similarDocuments,
                                    style: TextStyle(
                                      color: Theme.of(context)
                                          .colorScheme
                                          .onPrimaryContainer,
                                    ),
                                  ),
                                ),
                                // if (hasMultiUserSupport && false)
                                //   Tab(
                                //     child: Text(
                                //       "Permissions",
                                //       style: TextStyle(
                                //         color: Theme.of(context)
                                //             .colorScheme
                                //             .onPrimaryContainer,
                                //       ),
                                //     ),
                                //   ),
                              ],
                            ),
                          ),
                        );
                      },
                    ),
                  ),
                ],
                body: BlocBuilder<DocumentDetailsCubit, DocumentDetailsState>(
                  builder: (context, state) {
                    return BlocProvider(
                      create: (context) => SimilarDocumentsCubit(
                        context.read(),
                        context.read(),
                        context.read(),
                        context.read(),
                        documentId: widget.id,
                      ),
                      child: Padding(
                        padding: const EdgeInsets.symmetric(
                          vertical: 16,
                          horizontal: 16,
                        ),
                        child: TabBarView(
                          children: [
                            CustomScrollView(
                              slivers: [
                                SliverOverlapInjector(
                                  handle: NestedScrollView
                                      .sliverOverlapAbsorberHandleFor(context),
                                ),
                                switch (state) {
                                  DocumentDetailsLoaded(
                                    document: var document
                                  ) =>
                                    DocumentOverviewWidget(
                                      document: document,
                                      itemSpacing: _itemSpacing,
                                      queryString:
                                          widget.titleAndContentQueryString,
                                    ),
                                  DocumentDetailsError() => _buildErrorState(),
                                  _ => _buildLoadingState(),
                                },
                              ],
                            ),
                            CustomScrollView(
                              slivers: [
                                SliverOverlapInjector(
                                  handle: NestedScrollView
                                      .sliverOverlapAbsorberHandleFor(context),
                                ),
                                switch (state) {
                                  DocumentDetailsLoaded(
                                    document: var document
                                  ) =>
                                    DocumentContentWidget(
                                      document: document,
                                      queryString:
                                          widget.titleAndContentQueryString,
                                    ),
                                  DocumentDetailsError() => _buildErrorState(),
                                  _ => _buildLoadingState(),
                                }
                              ],
                            ),
                            CustomScrollView(
                              slivers: [
                                SliverOverlapInjector(
                                  handle: NestedScrollView
                                      .sliverOverlapAbsorberHandleFor(context),
                                ),
                                switch (state) {
                                  DocumentDetailsLoaded(
                                    document: var document,
                                    metaData: var metaData,
                                  ) =>
                                    DocumentMetaDataWidget(
                                      document: document,
                                      itemSpacing: _itemSpacing,
                                      metaData: metaData,
                                    ),
                                  DocumentDetailsError() => _buildErrorState(),
                                  _ => _buildLoadingState(),
                                },
                              ],
                            ),
                            CustomScrollView(
                              controller: _pagingScrollController,
                              slivers: [
                                SliverOverlapInjector(
                                  handle: NestedScrollView
                                      .sliverOverlapAbsorberHandleFor(context),
                                ),
                                SimilarDocumentsView(
                                  pagingScrollController:
                                      _pagingScrollController,
                                ),
                              ],
                            ),
                            // if (hasMultiUserSupport && false)
                            //   CustomScrollView(
                            //     controller: _pagingScrollController,
                            //     slivers: [
                            //       SliverOverlapInjector(
                            //         handle: NestedScrollView
                            //             .sliverOverlapAbsorberHandleFor(
                            //                 context),
                            //       ),
                            //       DocumentPermissionsWidget(
                            //         document: state.document,
                            //       ),
                            //     ],
                            //   ),
                          ],
                        ),
                      ),
                    );
                  },
                ),
              ),
            ),
          );
        },
      ),
    );
  }

  Widget _buildEditButton(DocumentModel document) {
    final currentUser = context.watch<LocalUserAccount>();

    bool canEdit = context.watchInternetConnection &&
        currentUser.paperlessUser.canEditDocuments;
    if (!canEdit) {
      return const SizedBox.shrink();
    }
    return Tooltip(
      message: S.of(context)!.editDocumentTooltip,
      preferBelow: false,
      verticalOffset: 40,
      child: FloatingActionButton(
        heroTag: "fab_document_details",
        child: const Icon(Icons.edit),
        onPressed: () => EditDocumentRoute(document).push(context),
      ),
    );
  }

  Widget _buildErrorState() {
    return SliverToBoxAdapter(
      child: Center(
        child: Text("Could not load document."),
      ),
    );
  }

  Widget _buildLoadingState() {
    return SliverFillRemaining(
      child: Center(
        child: CircularProgressIndicator(),
      ),
    );
  }

  BlocBuilder<DocumentDetailsCubit, DocumentDetailsState> _buildBottomAppBar() {
    return BlocBuilder<DocumentDetailsCubit, DocumentDetailsState>(
      builder: (context, state) {
        final currentUser = context.watch<LocalUserAccount>();
        return BottomAppBar(
          child: Builder(
            builder: (context) {
              return switch (state) {
                DocumentDetailsLoaded(document: var document) => Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: [
                      ConnectivityAwareActionWrapper(
                        disabled: !currentUser.paperlessUser.canDeleteDocuments,
                        offlineBuilder: (context, child) {
                          return const IconButton(
                            icon: Icon(Icons.delete),
                            onPressed: null,
                          ).paddedSymmetrically(horizontal: 4);
                        },
                        child: IconButton(
                          tooltip: S.of(context)!.deleteDocumentTooltip,
                          icon: const Icon(Icons.delete),
                          onPressed: () => _onDelete(document),
                        ).paddedSymmetrically(horizontal: 4),
                      ),
                      ConnectivityAwareActionWrapper(
                        offlineBuilder: (context, child) =>
                            const DocumentDownloadButton(
                          document: null,
                          enabled: false,
                        ),
                        child: DocumentDownloadButton(
                          document: document,
                        ),
                      ),
                      ConnectivityAwareActionWrapper(
                        offlineBuilder: (context, child) => const IconButton(
                          icon: Icon(Icons.open_in_new),
                          onPressed: null,
                        ),
                        child: IconButton(
                          tooltip: S.of(context)!.openInSystemViewer,
                          icon: const Icon(Icons.open_in_new),
                          onPressed: _onOpenFileInSystemViewer,
                        ).paddedOnly(right: 4.0),
                      ),
                      DocumentShareButton(document: document),
                      IconButton(
                        tooltip: S.of(context)!.print,
                        onPressed: () => context
                            .read<DocumentDetailsCubit>()
                            .printDocument(),
                        icon: const Icon(Icons.print),
                      ),
                    ],
                  ),
                _ => SizedBox.shrink(),
              };
            },
          ),
        );
      },
    );
  }

  void _onOpenFileInSystemViewer() async {
    final status =
        await context.read<DocumentDetailsCubit>().openDocumentInSystemViewer();
    if (status == ResultType.done) return;
    if (status == ResultType.noAppToOpen) {
      showGenericError(context, S.of(context)!.noAppToDisplayPDFFilesFound);
    }
    if (status == ResultType.fileNotFound) {
      showGenericError(context, translateError(context, ErrorCode.unknown));
    }
    if (status == ResultType.permissionDenied) {
      showGenericError(
          context, S.of(context)!.couldNotOpenFilePermissionDenied);
    }
  }

  void _onDelete(DocumentModel document) async {
    final delete = await showDialog(
          context: context,
          builder: (context) =>
              DeleteDocumentConfirmationDialog(document: document),
        ) ??
        false;
    if (delete) {
      try {
        await context.read<DocumentDetailsCubit>().delete(document);
        // showSnackBar(context, S.of(context)!.documentSuccessfullyDeleted);
      } on PaperlessApiException catch (error, stackTrace) {
        showErrorMessage(context, error, stackTrace);
      } finally {
        do {
          context.pop();
        } while (context.canPop());
      }
    }
  }
}
