import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:provider/provider.dart';
import 'dart:io';

extension ExtendedText on Widget {
  showOverlay({double? width, double? height}) {
    return Container(
      width: width ?? double.infinity,
      height: height ?? 60,
      decoration: BoxDecoration(
        gradient: LinearGradient(colors: [
          Colors.black.withOpacity(0.2),
          Colors.black.withOpacity(0.1),
          Colors.black.withOpacity(0.004),
        ], begin: Alignment.topCenter, end: Alignment.bottomCenter, tileMode: TileMode.clamp),
      ),
      child: this,
    );
  }
}

extension ContainerExt on Widget {
  Widget toWhiteContainer(
      {required double width, double? allPading, EdgeInsets? pading, EdgeInsets? margin, VoidCallback? onTap, Color? backgroundColor, bool isBorderRequired = false, double borderRadius = 0}) {
    return InkWell(
      onTap: onTap,
      child: Container(
        decoration: BoxDecoration(
          border: isBorderRequired ? Border.all(color: MyColors.darkPrimaryColor, width: 2) : null,
          color: backgroundColor ?? MyColors.white,
          borderRadius: BorderRadius.circular(borderRadius),
          boxShadow: [
            BoxShadow(
              color: const Color(0xff000000).withOpacity(.07),
              blurRadius: 26,
              offset: const Offset(0, -3),
            ),
            // BoxShadow(
            //   blurRadius: 8,
            //   spreadRadius: 3,
            //   offset: Offset(0, 3),
            //   color: MyColors.greyShadowColor,
            // ),
          ],
        ),
        padding: pading ?? EdgeInsets.all(allPading ?? 0),
        margin: margin,
        child: this,
      ),
    );
  }

  // Widget toContainer({required double borderRadius, required Color backgroundColor, required EdgeInsetsGeometry padding}) {
  //   return Container(
  //     decoration: BoxDecoration(color: backgroundColor, borderRadius: BorderRadius.circular(borderRadius)),
  //     padding: padding,
  //     child: this,
  //   );
  // }

  Widget toContainer({
    double borderRadius = 8,
    double paddingAll = 10,
    double marginAll = 0,
    EdgeInsetsGeometry? margin,
    EdgeInsetsGeometry? padding,
    Color backgroundColor = Colors.white,
    bool isShadowEnabled = false,
    bool isEnabledBorder = false,
    Color borderColor = Colors.black,
    double borderWidget = 1,
    double? width,
    double? height,
  }) =>
      Container(
        decoration: BoxDecoration(
          color: backgroundColor,
          borderRadius: BorderRadius.circular(borderRadius),
          border: !isEnabledBorder ? null : Border.all(color: borderColor, width: borderWidget),
          boxShadow: !isShadowEnabled
              ? null
              : [
                  BoxShadow(
                    color: const Color(0xff000000).withOpacity(.05),
                    blurRadius: 26,
                    offset: const Offset(0, -3),
                  ),
                ],
        ),
        padding: padding ?? EdgeInsets.all(paddingAll),
        margin: margin ?? EdgeInsets.all(marginAll),
        width: width,
        height: height,
        child: this,
      );
}

extension ImageExt on Widget {
  Widget toCircle({required double borderRadius}) {
    return ClipRRect(
      clipBehavior: Clip.hardEdge,
      borderRadius: BorderRadius.circular(borderRadius),
      child: this,
    );
  }
}

extension ActionIcon on Widget {
  Widget toCircleContainer() {
    return Container(
      height: 44,
      width: 44,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
        border: Border.all(color: MyColors.lightTextColor),
      ),
      child: this,
    );
  }
}

extension WidgetExt on Widget {
  Widget toWidget() {
    return this;
  }

  Widget sized({double? width, double? height}) {
    return SizedBox(
      width: width,
      height: height,
      child: this,
    );
  }

  Widget inkWell({required VoidCallback onTap, double radius = 0}) {
    return InkWell(
      onTap: onTap,
      child: Material(
        color: Colors.transparent,
        child: this,
      ),
    );
  }

  Widget sizeSq(double size) {
    return SizedBox(
      width: size,
      height: size,
      child: this,
    );
  }

  Widget fillParent({double hFactor = 1, double? vFactor}) {
    return FractionallySizedBox(
      heightFactor: null,
      widthFactor: hFactor,
      child: this,
    );
  }

  Widget margin({double top = 0, double bottom = 0, double left = 0, double right = 0}) {
    var pad = EdgeInsets.only(top: top, left: left, bottom: bottom, right: right);
    try {
      (this as dynamic).margin = pad;
    } catch (err) {
      return Padding(
        padding: pad,
        child: this,
      );
    }
    return this;
  }

  Widget toClip({double r = 40}) {
    return ClipRRect(
      borderRadius: BorderRadius.all(
        Radius.circular(r),
      ),
      clipBehavior: Clip.antiAlias,
      child: this,
    );
  }

  // Widget scrollable({Axis? direction, bool fadingEdge = true}) {
  //   var scrollview = SingleChildScrollView(
  //     child: this,
  //     controller: ScrollController(),
  //     scrollDirection: direction ?? Axis.vertical,
  //   );
  //   return fadingEdge ? scrollview.fadingEdge() : scrollview;
  // }

  Widget expand() {
    return Expanded(
      child: this,
    );
  }

  Widget align(Alignment alignment) {
    return Align(
      alignment: alignment,
      child: this,
    );
  }

  Widget center() {
    return Center(
      child: this,
    );
  }

  Widget padding(EdgeInsets padding) {
    return Padding(
      padding: padding,
      child: this,
    );
  }

  Widget paddingAll(double padding) {
    return Padding(
      padding: EdgeInsets.all(padding),
      child: this,
    );
  }

  Widget horPaddingMain() {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 21),
      child: this,
    );
  }

  Widget paddingOnly({double left = 0.0, double right = 0.0, double top = 0.0, double bottom = 0.0}) =>
      Padding(padding: EdgeInsets.only(left: left, right: right, top: top, bottom: bottom), child: this);

  // Widget onTap(VoidCallback onTap, {double corners = 0}) {
  //   return Clickable.widget(child: this, corners: corners, onTap: onTap);
  // }

  Widget ignoreInteraction() {
    return IgnorePointer(
      child: this,
    );
  }
}

// extension xScrollView on ScrollView {
//   Widget fadingEdge() => FadingEdgeScrollView.fromScrollView(
//     child: this,
//     gradientFractionOnEnd: 0.08,
//     gradientFractionOnStart: 0.08,
//     shouldDisposeScrollController: true,
//   );
// }
//
// extension x2ScrollView on SingleChildScrollView {
//   Widget fadingEdge() => FadingEdgeScrollView.fromSingleChildScrollView(
//     child: this,
//     gradientFractionOnEnd: 0.08,
//     gradientFractionOnStart: 0.08,
//     shouldDisposeScrollController: true,
//   );
// }

class Position {
  final double x, y, w, h;

  Position(this.x, this.y, this.w, this.h);
}

extension KeyExt on GlobalKey {
  Position globalPosition() {
    RenderBox box = currentContext!.findRenderObject() as RenderBox;
    Offset xy = box.localToGlobal(Offset.zero);
    Size wh = box.size;
    return Position(xy.dx, xy.dy, wh.width, wh.height);
  }
}

extension StateExt on State {
  reload({VoidCallback? b}) {
    setState(b ?? () {});
  }
}

// extension LocatiionExt on Location {
//   LatLng toLatLng() {
//     return LatLng(lat!, lng!);
//   }
// }

// extension xList<T> on List<T> {
//   T randomItem() {
//     final random = new Random();
//     var i = random.nextInt(this.length);
//     return this[i];
//   }
//
//   List<T> append(List<T> items) {
//     this.addAll(items);
//     return this;
//   }
//
//   bool isFirst(T item) => first == item;
//
//   bool isLast(T item) => last == item;
//
//   getOneByOne(
//       {required int delayMillis,
//       required Function(T) callback, VoidCallback? complete}) async {
//     for (var i in this) {
//       await delay(delayMillis);
//       callback(i);
//     }
//     complete!();
//   }
// }

extension xFuture<T> on Future<T?> {
  thenWithDelay(int millis, Function(T) thenBlock) {
    then((value) {
      Future.delayed(Duration(milliseconds: millis)).then((value) => thenBlock(value));
    });
  }
}

extension xDouble on int {
  Duration durationMillis() => Duration(milliseconds: this);

  Duration durationSec() => Duration(seconds: this);

  Duration durationHour() => Duration(hours: this);
}

extension BuildSVG on String? {
  Widget buildFileImage({double? height, double? width, BoxFit fit = BoxFit.contain, Color? color}) {
    if (this == null || this!.isEmpty || !File(this!).existsSync()) {
      return SizedBox(
        height: height,
        width: width,
        child: SvgPicture.asset(MyAssets.providersIcon, color: MyColors.darkPrimaryColor).paddingAll(15),
      );
    }
    return Image.file(
      File(this!),
      fit: fit,
      color: color,
      height: height,
      width: width,
    );
  }

  Widget buildSvg({double? height, double? width, BoxFit fit = BoxFit.contain, Color? color}) {
    return SvgPicture.asset(
      this!,
      fit: fit,
      color: color,
      height: height,
      width: width,
    );
  }

  Widget buildNetworkImage({double? height, double? width, BoxFit fit = BoxFit.contain, Color? color}) {
    if (this == null || this!.isEmpty) {
      return SizedBox(
        height: height,
        width: width,
        child: Image.asset(
          MyAssets.brokenImage,
          fit: BoxFit.fill,
        ),
      );
    }

    return Image.network(
      this!,
      errorBuilder: (BuildContext context, Object obj, StackTrace? s) {
        return Container(
          height: height,
          width: width,
          decoration: BoxDecoration(border: Border.all(color: MyColors.roundedCrossBgColor)),
          child: Icon(
            Icons.image_not_supported_outlined,
            color: MyColors.roundedCrossBgColor,
            size: width,
          ),
        );
      },
      loadingBuilder: (BuildContext context, Widget? child, ImageChunkEvent? imageChunk) {
        if (imageChunk == null) {
          return child!;
        }
        return SizedBox(
          height: height,
          width: width,
          child: const Center(
            child: CircularProgressIndicator(
              strokeWidth: 0.5,
              color: MyColors.darkPrimaryColor,
            ),
          ),
        );
      },
      fit: fit,
      color: color,
      height: height,
      width: width,
    );
  }
}

extension LocaleSetup on MultiProvider {
  Widget setupLocale() {
    return EasyLocalization(
        supportedLocales: MyLocales.supportedLocales,
        fallbackLocale: MyLocales.fallBackLocale,
        startLocale: MyLocales.startLocale,
        assetLoader: MyLocales.assetLoader,
        path: MyLocales.localesAssetPath,
        child: this);
  }
}

extension WidgetExtensions on Widget {
  Widget onPress(VoidCallback onTap) => InkWell(onTap: onTap, child: this);
}

extension ViewOnlyExtension on Widget {
  Widget toViewOnly(BuildContext context, {required Function() onTap}) {
    return GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
          if (AppState().getIsViewOnly) {
            onTap();
          }
        },
        child: AbsorbPointer(absorbing: AppState().getIsViewOnly, child: this));
  }
}

extension PreferredSizeWidgetViewOnlyExtension on PreferredSizeWidget {
  PreferredSizeWidget toViewOnly(BuildContext context, {required Function() onTap}) {
    return PreferredSize(
      preferredSize: preferredSize,
      child: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
          if (AppState().getIsViewOnly) {
            onTap();
          }
        },
        child: AbsorbPointer(
          absorbing: AppState().getIsViewOnly,
          child: this,
        ),
      ),
    );
  }
}
