import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:image_blur_detection/image_blur_detection.dart';
import 'package:image_picker/image_picker.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/modules/asset_delivery_module/provider/attachment_type_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/views/widgets/item_views/info_header_widget.dart';
import 'package:test_sa/views/widgets/item_views/info_text_widget.dart';

import '../../../new_views/common_widgets/app_dashed_button.dart';
import 'multi_image_picker_item.dart';

class AttachmentModel {
  int id = 0;
  File? file;

  AttachmentModel(this.id, this.file);

  factory AttachmentModel.fromJson(Map<String, dynamic> json) {
    return AttachmentModel(
      json['id'] ?? 0,
      json['file'] != null ? File(json['file']) : null,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'file': file?.path,
    };
  }
}

class AttachmentPicker extends StatefulWidget {
  final String pickerTitle;
  final String label;
  final bool error;
  final List<GenericAttachmentModel> attachment;

  final bool enabled, onlyImages;
  double? buttonHeight;
  Widget? buttonIcon;
  Color? buttonColor;
  final Function(List<GenericAttachmentModel>)? onChange;
  final bool showAsListView;
  final bool pickMultiple;
  Lookup? documentType;
  Widget? child;
  bool checkQuality;

  AttachmentPicker(
      {Key? key,
      this.attachment = const <GenericAttachmentModel>[],
      required this.label,
      this.pickerTitle = "Attach File",
      this.error = false,
      this.buttonHeight,
        required this.showAsListView,
      this.buttonIcon,
      this.enabled = true,
      this.onlyImages = false,
      this.onChange,
      this.documentType,
      // this.showAsListView = false,
      this.pickMultiple = false,
      this.checkQuality = false,
      this.child,
      this.buttonColor})
      : super(key: key);

  @override
  State<AttachmentPicker> createState() => _AttachmentPickerState();
}

class _AttachmentPickerState extends State<AttachmentPicker> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  Lookup? documentLookup;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      duration: const Duration(milliseconds: 1200),
      vsync: this,
    );
    _animationController.forward();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.child != null
        ? widget.child!.onPress((widget.enabled == false) ? () {} : () => onFilePicker(widget.checkQuality))
        : Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            spacing: 12,
            children: [
              AppDashedButton(
                  title: widget.label,
                  height: widget.buttonHeight,
                  buttonColor: widget.buttonColor,
                  icon: widget.buttonIcon,
                  onPressed: (widget.enabled == false) ? () {} : () => onFilePicker(widget.checkQuality)),
              if (widget.attachment.isNotEmpty)
                widget.showAsListView
                    ? ListView.separated(
                        shrinkWrap: true,
                        physics: const NeverScrollableScrollPhysics(),
                        padding: const EdgeInsets.only(top: 0),
                        itemBuilder: (cxt, index) {
                          File image = File(widget.attachment[index].name!);
                          return MultiFilesPickerItem(
                            file: image,
                            showAsListView: widget.showAsListView,
                            enabled: widget.enabled,
                            documentType: widget.attachment[index].documentType?.name,
                            onRemoveTap: (image) {
                              if (!widget.enabled) {
                                return;
                              }
                              widget.attachment.removeAt(index);
                              if (widget.onChange != null) {
                                widget.onChange!(widget.attachment);
                              }
                              setState(() {});
                            },
                          );
                        },
                        separatorBuilder: (cxt, index) => const Divider().defaultStyle(context),
                        itemCount: widget.attachment.length)
                    : Wrap(
                        spacing: 8.toScreenWidth,
                        children: List.generate(
                          widget.attachment.length,
                          (index) {
                            File image = File(widget.attachment[index].name!);
                            return MultiFilesPickerItem(
                              file: image,
                              enabled: widget.enabled,
                              onRemoveTap: (image) {
                                if (!widget.enabled) {
                                  return;
                                }
                                widget.attachment.removeAt(index);
                                if (widget.onChange != null) {
                                  widget.onChange!(widget.attachment);
                                }
                                setState(() {});
                              },
                            );
                          },
                        ),
                      ).paddingOnly(top: 0),
            ],
          );
  }

  fromFilePicker() async {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowMultiple: true,
      allowedExtensions: widget.onlyImages ? ['jpg', 'jpeg', 'png'] : ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xlsx', 'pptx'],
    );
    if (result != null) {
      for (var path in result.paths) {
        widget.attachment.add(GenericAttachmentModel(id: 0, name: File(path!).path, documentType: documentLookup));
      }
      if (widget.onChange != null) {
        widget.onChange!(widget.attachment);
      }
      setState(() {});
    }
  }

  Widget gridItem(IconData iconData, String title) {
    return Container(
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: AppColor.background(context),
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: AppColor.borderColor(context), width: 2),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Icon(iconData, color: AppColor.icon2Color(context), size: 24),
          title.bodyText2(context).custom(color: AppColor.labelTextStyleColor(context), fontSize: context.isTablet() ? 10.toScreenWidth : null),
          // Text(
          //   title,
          //   style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
          // ),
        ],
      ),
    );
  }

  onFilePicker(bool checkQuality) async {
    _animationController.reset();
    _animationController.forward();
    documentLookup = null;

    ImageSource? source = await showModalBottomSheet<ImageSource>(
      context: context,
      builder: (BuildContext context) {
        return StatefulBuilder(
          builder: (BuildContext context, StateSetter setModalState) {
            Widget listCard({required String icon, required String label, required VoidCallback onTap}) {
              bool isEnabled = documentLookup != null;
              return Container(
                padding: const EdgeInsets.all(12),
                decoration: BoxDecoration(
                  color: isEnabled ? AppColor.background(context) : AppColor.tabBarBackground(context),
                  borderRadius: BorderRadius.circular(16),
                  border: Border.all(color: AppColor.borderColor(context), width: 2),
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    icon.toSvgAsset(width: 24, height: 24, color: isEnabled ? AppColor.icon2Color(context) : AppColor.icon2Color(context).withOpacity(0.4)),
                    label.bodyText2(context).custom(
                        color: isEnabled ? AppColor.labelTextStyleColor(context) : AppColor.labelTextStyleColor(context).withOpacity(0.4), fontSize: context.isTablet() ? 10.toScreenWidth : null),
                  ],
                ),
              ).onPress(() {
                if (!isEnabled) return;
                onTap();
              });
            }

            List<Widget> listItems = [
              listCard(
                icon: 'camera_icon',
                label: '${context.translation.open}\n${context.translation.camera}',
                onTap: () {
                  Navigator.of(context).pop(ImageSource.camera);
                },
              ),
              listCard(
                icon: 'gallery_icon',
                label: '${context.translation.open}\n${context.translation.gallery}',
                onTap: () {
                  Navigator.of(context).pop(ImageSource.gallery);
                },
              ),
              listCard(
                icon: 'file_icon',
                label: '${context.translation.open}\n${context.translation.files}',
                onTap: () async {
                  await fromFilePicker();
                  Navigator.pop(context);
                },
              ),
            ];

            return SafeArea(
              top: false,
              child: Container(
                width: double.infinity,
                decoration: BoxDecoration(
                  color: AppColor.bottomSheetColor(context),
                  borderRadius: const BorderRadius.only(
                    topRight: Radius.circular(30),
                    topLeft: Radius.circular(30),
                  ),
                ),
                padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Align(alignment: AlignmentDirectional.center,
                      child: Container(
                        width: 40.toScreenWidth,
                        height: 5.toScreenHeight,
                        decoration: BoxDecoration(color: AppColor.neutral40, borderRadius: BorderRadius.circular(30)),
                      ),
                    ),
                    8.height,
                     InfoHeader16Widget(widget.pickerTitle),
                    8.height,
                    SingleItemDropDownMenu<Lookup, AttachmentTypeLookupProviderLatest>(
                      context: context,
                      height: 56.toScreenHeight,
                      title: "Document Type",
                      initialValue: documentLookup,
                      showShadow: false,
                      backgroundColor: AppColor.fieldBgColor(context),
                      showAsBottomSheet: true,
                      onSelect: (value) {
                        documentLookup = value;
                        setModalState(() {});
                      },
                    ),
                    if (documentLookup == null) ...[
                      4.height,
                      const InfoTextLabelWidget(label: 'Please Select Document Type before picking file', color: AppColor.red30),
                    ],
                    GridView.builder(
                      padding: const EdgeInsets.only(top: 16, bottom: 0),
                      shrinkWrap: true,
                      physics: const NeverScrollableScrollPhysics(),
                      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1, crossAxisSpacing: 16, mainAxisSpacing: 16),
                      itemCount: listItems.length,
                      itemBuilder: (context, index) {
                        final delay = index * 0.08;
                        final animation = Tween<double>(begin: 0.0, end: 1.0).animate(
                          CurvedAnimation(
                            parent: _animationController,
                            curve: Interval(
                              delay.clamp(0.0, 0.8),
                              (delay + 0.3).clamp(0.0, 1.0),
                              curve: Curves.easeOut,
                            ),
                          ),
                        );

                        final slideAnimation = Tween<Offset>(
                          begin: const Offset(0.0, 0.3),
                          end: Offset.zero,
                        ).animate(
                          CurvedAnimation(
                            parent: _animationController,
                            curve: Interval(
                              delay.clamp(0.0, 0.8),
                              (delay + 0.3).clamp(0.0, 1.0),
                              curve: Curves.easeOutCubic,
                            ),
                          ),
                        );

                        return FadeTransition(
                          opacity: animation,
                          child: SlideTransition(position: slideAnimation, child: listItems[index]),
                        );
                      },
                    ),
                  ],
                ),
              ),
            );
          },
        );
      },
    );
    if (source == null) return;

    if (widget.pickMultiple && source == ImageSource.gallery) {
      final pickedFiles = await ImagePicker().pickMultiImage(imageQuality: 70);
      if (pickedFiles.isNotEmpty) {
        pickedFiles.forEach((pickedFile) {
          File fileImage = File(pickedFile.path);

          widget.attachment.add(GenericAttachmentModel(id: 0, name: fileImage.path, documentType: documentLookup));
        });
        if (widget.onChange != null) {
          widget.onChange!(widget.attachment);
        }
        setState(() {});
      }
      return;
    }

    final pickedFile = await ImagePicker().pickImage(source: source, imageQuality: 50);

    if (pickedFile != null) {
      File fileImage = File(pickedFile.path);

      if (checkQuality) {
        ImageQualityValidator imageQualityValidator = ImageQualityValidator();
        final result = await imageQualityValidator.validate(await fileImage.readAsBytes());

        if (!result.isValid) {
          String issues = "Your image have following problems:";
          result.issues.forEach((issue) => (issues += "\n- $issue"));
          context.showInfoDialog(issues, title: "Bad Quality Found");
          return;
        }
      }

      widget.attachment.add(GenericAttachmentModel(id: 0, name: fileImage.path, documentType: documentLookup));
      if (widget.onChange != null) {
        widget.onChange!(widget.attachment);
      }
      setState(() {});
    }
  }
}
