import 'package:flutter/widgets.dart';

import 'package:collection/collection.dart';

import 'package:go_router/go_router.dart';

import 'package:pshared/models/payment/type.dart';

import 'package:pweb/widgets/sidebar/destinations.dart';


class PayoutRoutes {
  static const dashboard = 'dashboard';
  static const sendPayout = payment;
  static const recipients = 'payout-recipients';
  static const invitations = 'payout-invitations';
  static const addRecipient = 'payout-add-recipient';
  static const payment = 'payout-payment';
  static const settings = 'payout-settings';
  static const reports = 'payout-reports';
  static const methods = 'payout-methods';
  static const editWallet = 'payout-edit-wallet';
  static const walletTopUp = 'payout-wallet-top-up';

  static const paymentTypeQuery = 'paymentType';
  static const returnToQuery = 'returnTo';

  static const dashboardPath = '/dashboard';
  static const recipientsPath = '/dashboard/recipients';
  static const invitationsPath = '/dashboard/invitations';
  static const addRecipientPath = '/dashboard/recipients/add';
  static const paymentPath = '/dashboard/payment';
  static const settingsPath = '/dashboard/settings';
  static const reportsPath = '/dashboard/reports';
  static const methodsPath = '/dashboard/methods';
  static const editWalletPath = '/dashboard/methods/edit';
  static const walletTopUpPath = '/dashboard/wallet/top-up';

  static String nameFor(PayoutDestination destination) {
    switch (destination) {
      case PayoutDestination.dashboard:
        return dashboard;
      case PayoutDestination.sendPayout:
      return payment;
    case PayoutDestination.recipients:
      return recipients;
    case PayoutDestination.invitations:
      return invitations;
    case PayoutDestination.addrecipient:
      return addRecipient;
    case PayoutDestination.payment:
      return payment;
    case PayoutDestination.settings:
        return settings;
      case PayoutDestination.reports:
        return reports;
      case PayoutDestination.methods:
        return methods;
      case PayoutDestination.editwallet:
        return editWallet;
      case PayoutDestination.walletTopUp:
        return walletTopUp;
    }
  }

  static String pathFor(PayoutDestination destination) {
    switch (destination) {
      case PayoutDestination.dashboard:
        return dashboardPath;
      case PayoutDestination.sendPayout:
      return paymentPath;
    case PayoutDestination.recipients:
      return recipientsPath;
    case PayoutDestination.invitations:
      return invitationsPath;
    case PayoutDestination.addrecipient:
      return addRecipientPath;
    case PayoutDestination.payment:
      return paymentPath;
    case PayoutDestination.settings:
        return settingsPath;
      case PayoutDestination.reports:
        return reportsPath;
      case PayoutDestination.methods:
        return methodsPath;
      case PayoutDestination.editwallet:
        return editWalletPath;
      case PayoutDestination.walletTopUp:
        return walletTopUpPath;
    }
  }

  static PayoutDestination? destinationFor(String? routeName) {
    switch (routeName) {
      case dashboard:
        return PayoutDestination.dashboard;
      case sendPayout:
      return PayoutDestination.payment;
    case recipients:
      return PayoutDestination.recipients;
    case invitations:
      return PayoutDestination.invitations;
    case addRecipient:
      return PayoutDestination.addrecipient;
    case settings:
      return PayoutDestination.settings;
      case reports:
        return PayoutDestination.reports;
      case methods:
        return PayoutDestination.methods;
      case editWallet:
        return PayoutDestination.editwallet;
      case walletTopUp:
        return PayoutDestination.walletTopUp;
      default:
        return null;
    }
  }

  static Map<String, String> buildQueryParameters({
    PaymentType? paymentType,
    PayoutDestination? returnTo,
  }) {
    final params = <String, String>{
      if (paymentType != null) paymentTypeQuery: paymentType.name,
      if (returnTo != null) returnToQuery: nameFor(returnTo),
    };
    return params;
  }

  static PaymentType? paymentTypeFromState(GoRouterState state) =>
      paymentTypeFromRaw(state.uri.queryParameters[paymentTypeQuery]);

  static PaymentType? paymentTypeFromRaw(String? raw) => raw == null
      ? null
      : PaymentType.values.firstWhereOrNull((type) => type.name == raw);

  static PayoutDestination fallbackFromState(
    GoRouterState state, {
    PayoutDestination defaultDestination = PayoutDestination.dashboard,
  }) {
    final raw = state.uri.queryParameters[returnToQuery];
    return destinationFor(raw) ?? defaultDestination;
  }
}

extension PayoutNavigation on BuildContext {
  void goToPayout(PayoutDestination destination) => goNamed(PayoutRoutes.nameFor(destination));

  void pushToPayout(PayoutDestination destination) => pushNamed(PayoutRoutes.nameFor(destination));

  void goToPayment({
    PaymentType? paymentType,
    PayoutDestination? returnTo,
  }) =>
      goNamed(
        PayoutRoutes.payment,
        queryParameters: PayoutRoutes.buildQueryParameters(
          paymentType: paymentType,
          returnTo: returnTo,
        ),
      );

  void pushToPayment({
    PaymentType? paymentType,
    PayoutDestination? returnTo,
  }) =>
      pushNamed(
        PayoutRoutes.payment,
        queryParameters: PayoutRoutes.buildQueryParameters(
          paymentType: paymentType,
          returnTo: returnTo,
        ),
      );

  void pushToWalletTopUp({PayoutDestination? returnTo}) => pushNamed(
        PayoutRoutes.walletTopUp,
        queryParameters: PayoutRoutes.buildQueryParameters(returnTo: returnTo),
      );

  void pushToEditWallet({PayoutDestination? returnTo}) => pushNamed(
        PayoutRoutes.editWallet,
        queryParameters: PayoutRoutes.buildQueryParameters(returnTo: returnTo),
      );
}
