import 'package:comwell_key_app/overview/models/booking.dart';
import 'package:comwell_key_app/routing/app_routes.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_cubit.dart';
import 'package:comwell_key_app/up_sales/cubit/up_sales_state.dart';
import 'package:comwell_key_app/up_sales/models/addon_upgrade.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade.dart';
import 'package:comwell_key_app/up_sales/models/room_upgrade_list.dart';
import 'package:comwell_key_app/up_sales/pages/addon_upgrade_page.dart';
import 'package:comwell_key_app/up_sales/pages/processing/up_sales_error_page.dart';
import 'package:comwell_key_app/up_sales/pages/processing/up_sales_processing_page.dart';
import 'package:comwell_key_app/up_sales/pages/room_upgrade_page.dart';
import 'package:comwell_key_app/up_sales/pages/services_upgrade_page.dart';
import 'package:comwell_key_app/up_sales/pages/up_sale_confirmation_page.dart';
import 'package:comwell_key_app/up_sales/up_sales_catalog.dart';
import 'package:comwell_key_app/utils/locator.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';

final upSalesRoute = ShellRoute(
  pageBuilder: (context, state, child) {
    return CustomTransitionPage<void>(
      key: state.pageKey,
      child: BlocProvider(
        create: (_) {
          final extra = state.extra;
          final Booking booking;
          if (extra is List<dynamic>) {
            booking = extra[0] as Booking;
          } else if (extra is RoomUpgradeList) {
            booking = extra.booking;
          } else {
            throw StateError('Unexpected extras type: ${extra.runtimeType}');
          }
          return UpSalesCubit(
            upSaleRepository: locator(),
            booking: booking,
          );
        },
        child: child,
      ),
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        return SlideTransition(
          position:
              Tween<Offset>(
                begin: const Offset(1.0, 0.0),
                end: Offset.zero,
              ).animate(
                CurvedAnimation(
                  parent: animation,
                  curve: Curves.easeInOut,
                ),
              ),
          child: child,
        );
      },
      transitionDuration: const Duration(milliseconds: 250),
    );
  },
  routes: [
    GoRoute(
      path: AppRoutes.upSalesCatalog,
      builder: (context, state) {
        return const UpSalesCatalog();
      },
    ),
    GoRoute(
      path: AppRoutes.roomUpgrade,
      builder: (context, state) {
        return RoomUpgradePage(roomUpgradeList: state.extra as RoomUpgradeList);
      },
    ),
    GoRoute(
      path: AppRoutes.addonUpgrade,
      builder: (context, state) {
        final extras = state.extra as List<dynamic>;
        return AddonUpgradePage(
          addonUpgrade: extras[0] as AddOnUpgrade,
          extrasTotalPrice: extras[1] as int,
          selectedRoomUpgrade: extras[2] as String,
          onServingTimeSelected: extras[3] as void Function(TimeOfDay),
        );
      },
    ),
    GoRoute(
      path: AppRoutes.servicesUpgrade,
      builder: (context, state) {
        return ServicesUpgradePage(roomUpgradeList: state.extra as RoomUpgradeList);
      },
    ),
    GoRoute(
      path: AppRoutes.upSaleConfirmation,
      builder: (context, state) {
        final extras = state.extra as List<dynamic>;
        final selectedUpSales = extras[0] as List<AddOnUpgrade?>;
        final extrasTotalPrice = extras[1] as int;
        final selectedRoomUpgrade = extras[2] as RoomUpgrade?;
        return UpSaleConfirmationPage(
          selectedUpSales: selectedUpSales.whereType<AddOnUpgrade>().toList(),
          extrasTotalPrice: extrasTotalPrice,
          selectedRoomUpgrade: selectedRoomUpgrade,
        );
      },
    ),
    GoRoute(
      path: AppRoutes.upSalesProcessing,
      builder: (context, state) {
        final cubit = context.read<UpSalesCubit>();
        cubit.addUpSalesToBooking();

        return BlocBuilder<UpSalesCubit, UpSalesState>(
          builder: (context, state) {
            return UpSalesProcessingPage(key: ValueKey(state));
          },
        );
      },
    ),
    GoRoute(
      path: AppRoutes.upSalesError,
      builder: (context, state) => const UpSalesErrorPage(),
    ),
  ],
);