import 'package:converterpro/app_router.dart';
import 'package:converterpro/helpers/responsive_helper.dart';
import 'package:converterpro/models/conversions.dart';
import 'package:converterpro/models/currencies.dart';
import 'package:converterpro/models/hide_units.dart';
import 'package:converterpro/utils/utils_widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:translations/app_localizations.dart';
import 'package:converterpro/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:converterpro/data/property_unit_maps.dart';
import 'package:intl/intl.dart';
import 'package:vector_graphics/vector_graphics.dart';

class ConversionPage extends ConsumerWidget {
  final PROPERTYX property;

  const ConversionPage(this.property, {super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // if we remove the following check, if you enter the site directly to
    // '/conversions/:property' an error will occur
    if (!ref.watch(isEverythingLoadedProvider)) {
      return const SplashScreenWidget();
    }

    final l10n = AppLocalizations.of(context)!;

    final heroEnabled = ref.watch(conversionPageHeroEnabledProvider);

    final unitDataList = ref
        .watch(ConversionsNotifier.provider)
        .value![property]!;
    final propertyUiMap = getPropertyUiMap(context);
    final unitMap = getUnitUiMap(context)[property]!;
    final hiddenUnits = ref
        .watch(HiddenUnitsNotifier.provider)
        .value![property]!;
    final hiddenUnitData = unitDataList.where(
      (e) => hiddenUnits.contains(e.unit.name),
    ).toList();
    final unhiddenUnitData = unitDataList.where(
      (e) => !hiddenUnits.contains(e.unit.name),
    ).toList();

    Widget? subtitleWidget;
    if (property == PROPERTYX.currencies) {
      Currencies? currencies = ref.watch(CurrenciesNotifier.provider).value;
      if (currencies == null) {
        subtitleWidget = const SizedBox(
          height: 30,
          child: Center(
            child: SizedBox(
              width: 25,
              height: 25,
              child: CircularProgressIndicator(),
            ),
          ),
        );
      } else {
        subtitleWidget = Text(
          _getLastUpdateString(context, currencies.lastUpdate),
          style: Theme.of(context).textTheme.titleSmall,
        );
      }
    }

    UnitWidget unitWidgetBuilder(UnitData unitData) => UnitWidget(
      tffKey: unitData.unit.name.toString(),
      unitName: unitMap[unitData.unit.name]!,
      unitSymbol: unitData.unit.symbol,
      symbolContainsIcon: unitData.property == PROPERTYX.currencies,
      keyboardType: unitData.textInputType,
      controller: unitData.tec,
      validator: (String? input) {
        if (input != null) {
          if (input != '' && !unitData.getValidator().hasMatch(input)) {
            return l10n.invalidCharacters;
          }
        }
        return null;
      },
      onChanged: (String txt) {
        String newTxt = txt;
        bool changed = false;
        if (newTxt.contains(',')) {
          newTxt = newTxt.replaceAll(',', '.');
          changed = true;
        }
        if (newTxt.startsWith('.')) {
          newTxt = '0$newTxt';
          changed = true;
        }
        if (changed) {
          unitData.tec.value = TextEditingValue(
            text: newTxt,
            selection: TextSelection.collapsed(offset: newTxt.length),
          );
        }
        if (txt == '' || unitData.getValidator().hasMatch(txt)) {
          var conversions = ref.read(ConversionsNotifier.provider.notifier);
          //just numeral system uses a string for conversion
          if (unitData.property == PROPERTYX.numeralSystems) {
            conversions.convert(unitData, txt == "" ? null : txt, property);
          } else {
            conversions.convert(
              unitData,
              txt == "" ? null : double.parse(txt),
              property,
            );
          }
        }
      },
    );

    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraint) {
        final int numCols = responsiveNumCols(constraint.maxWidth);
        return CustomScrollView(
          slivers: <Widget>[
            SliverAppBar.large(
              title: Builder(
                builder: (context) {
                  final isExpanded =
                      (DefaultTextStyle.of(context).style.fontSize ?? 22.0) >
                      24.0;
                  final iconWidget = SvgPicture(
                    AssetBytesLoader(propertyUiMap[property]!.selectedIcon),
                    width: 24,
                    colorFilter: ColorFilter.mode(
                      Theme.of(context).textTheme.titleLarge!.color!,
                      BlendMode.srcIn,
                    ),
                  );
                  final textWidget = Material(
                    type: MaterialType.transparency,
                    child: Text(
                      propertyUiMap[property]!.name,
                      style: Theme.of(context).textTheme.headlineMedium,
                    ),
                  );
                  return Row(
                    spacing: 12,
                    children: [
                      isExpanded
                          ? HeroMode(
                              enabled: heroEnabled,
                              child: Hero(
                                tag: 'icon-${property.toString()}',
                                child: iconWidget,
                              ),
                            )
                          : iconWidget,
                      isExpanded
                          ? HeroMode(
                              enabled: heroEnabled,
                              child: Hero(
                                tag: 'text-${property.toString()}',
                                child: textWidget,
                              ),
                            )
                          : textWidget,
                    ],
                  );
                },
              ),
            ),
            if (subtitleWidget != null)
              SliverToBoxAdapter(
                child: Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 15),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [subtitleWidget],
                  ),
                ),
              ),
            SliverPadding(
              padding: const EdgeInsets.only(top: 10),
              sliver: SliverGrid.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: numCols,
                  childAspectRatio: responsiveChildAspectRatio(
                    constraint.maxWidth,
                    numCols,
                  ),
                ),
                itemCount: unhiddenUnitData.length,
                itemBuilder: (context, index) =>
                    unitWidgetBuilder(unhiddenUnitData[index]),
              ),
            ),
            if (hiddenUnitData.isNotEmpty)
              SliverToBoxAdapter(
                child: ExpansionTile(
                  leading: const Icon(Icons.visibility_off_outlined),
                  title: Text(
                    l10n.hiddenUnits,
                    style: Theme.of(context).textTheme.titleLarge,
                  ),
                  children: [
                    GridView.builder(
                      shrinkWrap: true,
                      physics: const NeverScrollableScrollPhysics(),
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: numCols,
                        childAspectRatio: responsiveChildAspectRatio(
                          constraint.maxWidth,
                          numCols,
                        ),
                      ),
                      itemCount: hiddenUnitData.length,
                      itemBuilder: (context, index) =>
                          unitWidgetBuilder(hiddenUnitData[index]),
                    ),
                  ],
                ),
              ),
            if (isDrawerFixed(MediaQuery.sizeOf(context).width))
              // Space for FAB + navigation bar (android)
              SliverToBoxAdapter(
                child: SizedBox(
                  height: 60 + MediaQuery.paddingOf(context).bottom,
                ),
              ),
          ],
        );
      },
    );
  }
}

String _getLastUpdateString(BuildContext context, String lastUpdate) {
  final l10n = AppLocalizations.of(context)!;
  DateTime lastUpdateCurrencies = DateTime.parse(lastUpdate);
  DateTime dateNow = DateTime.now();
  if (lastUpdateCurrencies.day == dateNow.day &&
      lastUpdateCurrencies.month == dateNow.month &&
      lastUpdateCurrencies.year == dateNow.year) {
    return l10n.lastCurrenciesUpdate + l10n.today;
  }
  return l10n.lastCurrenciesUpdate +
      DateFormat.yMd(
        Localizations.localeOf(context).languageCode,
      ).format(lastUpdateCurrencies);
}
