import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:selfprivacy/illustrations/stray_deer.dart';
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
import 'package:selfprivacy/logic/models/server_provider_location.dart';
import 'package:selfprivacy/logic/models/server_type.dart';
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
import 'package:selfprivacy/ui/components/info_box/info_box.dart';

class ServerTypePicker extends StatefulWidget {
  const ServerTypePicker({
    required this.serverInstallationCubit,
    super.key,
  });

  final ServerInstallationCubit serverInstallationCubit;

  @override
  State<ServerTypePicker> createState() => _ServerTypePickerState();
}

class _ServerTypePickerState extends State<ServerTypePicker> {
  ServerProviderLocation? serverProviderLocation;
  ServerType? serverType;

  void setServerProviderLocation(final ServerProviderLocation? location) {
    setState(() {
      serverProviderLocation = location;
    });
  }

  @override
  Widget build(final BuildContext context) {
    if (serverProviderLocation == null) {
      return SelectLocationPage(
        serverInstallationCubit: widget.serverInstallationCubit,
        callback: setServerProviderLocation,
      );
    }

    return SelectTypePage(
      location: serverProviderLocation!,
      serverInstallationCubit: widget.serverInstallationCubit,
      backToLocationPickingCallback: () {
        setServerProviderLocation(null);
      },
    );
  }
}

class SelectLocationPage extends StatelessWidget {
  const SelectLocationPage({
    required this.serverInstallationCubit,
    required this.callback,
    super.key,
  });

  final Function callback;
  final ServerInstallationCubit serverInstallationCubit;

  @override
  Widget build(final BuildContext context) => FutureBuilder(
        future: serverInstallationCubit.fetchAvailableLocations(),
        builder: (
          final BuildContext context,
          final AsyncSnapshot<Object?> snapshot,
        ) {
          if (snapshot.hasData) {
            if ((snapshot.data as List<ServerProviderLocation>).isEmpty) {
              return Text('initializing.no_locations_found'.tr());
            }
            return Column(
              children: [
                Text(
                  'initializing.choose_location_type'.tr(),
                  style: Theme.of(context).textTheme.headlineSmall,
                ),
                const SizedBox(height: 16),
                Text(
                  'initializing.choose_location_type_text'.tr(),
                  style: Theme.of(context).textTheme.bodyMedium,
                ),
                const SizedBox(height: 16),
                ...(snapshot.data! as List<ServerProviderLocation>).map(
                  (final location) => SizedBox(
                    width: double.infinity,
                    child: InkWell(
                      onTap: () {
                        callback(location);
                      },
                      child: Card(
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                '${location.flag ?? ''} ${location.title}',
                                style: Theme.of(context).textTheme.titleMedium,
                              ),
                              const SizedBox(height: 8),
                              if (location.description != null)
                                Text(
                                  location.description!,
                                  style: Theme.of(context).textTheme.bodyMedium,
                                ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 24),
              ],
            );
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
      );
}

class SelectTypePage extends StatelessWidget {
  const SelectTypePage({
    required this.backToLocationPickingCallback,
    required this.location,
    required this.serverInstallationCubit,
    super.key,
  });

  final ServerProviderLocation location;
  final ServerInstallationCubit serverInstallationCubit;
  final Function backToLocationPickingCallback;

  @override
  Widget build(final BuildContext context) => FutureBuilder(
        future: serverInstallationCubit.fetchAvailableTypesByLocation(location),
        builder: (
          final BuildContext context,
          final AsyncSnapshot<Object?> snapshot,
        ) {
          if (snapshot.hasData) {
            if ((snapshot.data as List<ServerType>).isEmpty) {
              return Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'initializing.locations_not_found'.tr(),
                    style: Theme.of(context).textTheme.headlineSmall,
                  ),
                  const SizedBox(height: 16),
                  Text(
                    'initializing.locations_not_found_text'.tr(),
                    style: Theme.of(context).textTheme.bodyMedium,
                  ),
                  LayoutBuilder(
                    builder: (final context, final constraints) => CustomPaint(
                      size: Size(
                        constraints.maxWidth,
                        (constraints.maxWidth * 1).toDouble(),
                      ),
                      painter: StrayDeerPainter(
                        colorScheme: Theme.of(context).colorScheme,
                        colorPalette: context
                            .read<AppSettingsCubit>()
                            .state
                            .corePaletteOrDefault,
                      ),
                    ),
                  ),
                  const SizedBox(height: 16),
                  BrandButton.rised(
                    onPressed: () {
                      backToLocationPickingCallback();
                    },
                    text: 'initializing.back_to_locations'.tr(),
                  ),
                ],
              );
            }
            return Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'initializing.choose_server_type'.tr(),
                  style: Theme.of(context).textTheme.headlineSmall,
                ),
                const SizedBox(height: 16),
                Text(
                  'initializing.choose_server_type_text'.tr(),
                  style: Theme.of(context).textTheme.bodyMedium,
                ),
                const SizedBox(height: 16),
                ...(snapshot.data! as List<ServerType>).map(
                  (final type) => SizedBox(
                    width: double.infinity,
                    child: InkWell(
                      onTap: () {
                        serverInstallationCubit.setServerType(type);
                      },
                      child: Card(
                        child: Padding(
                          padding: const EdgeInsets.all(16.0),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                type.title,
                                style: Theme.of(context).textTheme.titleMedium,
                              ),
                              const SizedBox(height: 8),
                              Row(
                                children: [
                                  Icon(
                                    Icons.memory_outlined,
                                    color:
                                        Theme.of(context).colorScheme.onSurface,
                                  ),
                                  const SizedBox(width: 8),
                                  Text(
                                    'server.core_count'.plural(type.cores),
                                    style:
                                        Theme.of(context).textTheme.bodyMedium,
                                  ),
                                ],
                              ),
                              const SizedBox(height: 8),
                              Row(
                                children: [
                                  Icon(
                                    Icons.memory_outlined,
                                    color:
                                        Theme.of(context).colorScheme.onSurface,
                                  ),
                                  const SizedBox(width: 8),
                                  Text(
                                    'initializing.choose_server_type_ram'
                                        .tr(args: [type.ram.toString()]),
                                    style:
                                        Theme.of(context).textTheme.bodyMedium,
                                  ),
                                ],
                              ),
                              const SizedBox(height: 8),
                              Row(
                                children: [
                                  Icon(
                                    Icons.sd_card_outlined,
                                    color:
                                        Theme.of(context).colorScheme.onSurface,
                                  ),
                                  const SizedBox(width: 8),
                                  Text(
                                    'initializing.choose_server_type_storage'
                                        .tr(
                                      args: [type.disk.gibibyte.toString()],
                                    ),
                                    style:
                                        Theme.of(context).textTheme.bodyMedium,
                                  ),
                                ],
                              ),
                              const SizedBox(height: 8),
                              const Divider(height: 8),
                              const SizedBox(height: 8),
                              Row(
                                children: [
                                  Icon(
                                    Icons.payments_outlined,
                                    color:
                                        Theme.of(context).colorScheme.onSurface,
                                  ),
                                  const SizedBox(width: 8),
                                  Text(
                                    'initializing.choose_server_type_payment_per_month'
                                        .tr(
                                      args: [
                                        '${type.price.value.toString()} ${type.price.currency}'
                                      ],
                                    ),
                                    style:
                                        Theme.of(context).textTheme.bodyLarge,
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 16),
                InfoBox(text: 'initializing.choose_server_type_notice'.tr()),
              ],
            );
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
      );
}
