import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/attachment.dart';
import 'package:test_sa/controllers/providers/api/parts_provider.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/service_request/service_report.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart';
import 'package:test_sa/providers/service_request_providers/loan_availability_provider.dart';
import 'package:test_sa/providers/work_order/reason_provider.dart';
import 'package:test_sa/providers/work_order/service_type_provider.dart';
import 'package:test_sa/views/pages/user/requests/work_order/part_no_button.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/equipment/pick_asset.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart';
import 'package:test_sa/views/widgets/status/report/service_report_last_call.dart';

import '../../../../../controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import '../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import '../../../../../models/lookup.dart';
import '../../../../../models/service_request/spare_parts.dart';
import '../../../../../new_views/common_widgets/app_text_form_field.dart';
import '../../../../../new_views/common_widgets/default_app_bar.dart';
import '../../../../../new_views/common_widgets/single_item_drop_down_menu.dart';
import '../../../../widgets/date_and_time/date_picker.dart';
import '../../../../widgets/images/multi_image_picker.dart';
import '../../../../widgets/status/report/service_report_fault_description.dart';
import '../../../../widgets/status/report/service_report_repair_location.dart';
import '../../../../widgets/timer/app_timer.dart';

class CreateServiceReport extends StatefulWidget {
  static const String id = "/create-service-report";
  final ServiceRequest request;

  const CreateServiceReport({Key? key, required this.request}) : super(key: key);

  @override
  _CreateServiceReportState createState() => _CreateServiceReportState();
}

class _CreateServiceReportState extends State<CreateServiceReport> with TickerProviderStateMixin {
  late UserProvider _userProvider;
  late SettingProvider _settingProvider;
  late ServiceRequestsProvider _serviceRequestsProvider;
  late ServiceStatusProvider _assetTypeProvider;
  late PartsProvider _partsProvider;
  late ServiceReport _serviceReport;
  bool _isLoading = false;
  List<SparePart> _spareParts = [];

  final List<GenericAttachmentModel> attachments = [];
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  final TextEditingController _faultController = TextEditingController();
  final TextEditingController _workPreformedController = TextEditingController();
  final TextEditingController _partQtyController = TextEditingController();

  @override
  void initState() {
    _serviceReport = ServiceReport(
      // returnToService: DateTime.now(),
      // //type: const Lookup(value: 2),
      // device: widget.request.device,
      sparePartsWorkOrders: [],
    );
    super.initState();
    if (context.mounted) {
      Provider.of<ServiceReportLastCallsProvider>(context, listen: false).reset();
      Provider.of<ReasonProvider>(context, listen: false).reset();
      Provider.of<ReasonProvider>(context, listen: false).serviceRequestId = widget.request.id!;
    }
    // _isLoading = true;
  }

  Asset? loanAvailabilityAsset;

  @override
  void dispose() {
    _faultController.dispose();
    _workPreformedController.dispose();
    _partQtyController.dispose();
    super.dispose();
  }

  void getRequestForWorkOrder() async {
    _isLoading = true;
    setState(() {});
    _serviceReport.callRequest = await _serviceRequestsProvider.getCallRequestForWorkOrder(callId: widget.request.id!);
    await _assetTypeProvider.getTypes();
    _serviceReport.assignedEmployee = _serviceReport.callRequest?.assignedEmployee;
    _serviceReport.equipmentStatus = _serviceReport.callRequest?.defectType;
    _serviceReport.serviceType = Lookup(id: 65, name: "Interval", value: 1); // default value in service type as in web
    _spareParts = await _partsProvider.getPartsList(assetId: widget.request.deviceId);
    _isLoading = false;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    _userProvider = Provider.of<UserProvider>(context);
    _settingProvider = Provider.of<SettingProvider>(context);
    _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
    _assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
    _partsProvider = Provider.of<PartsProvider>(context);
    if (_serviceReport.callRequest == null) {
      getRequestForWorkOrder();
    }
    _serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere(
      (element) => element.value == _serviceReport.callRequest?.assetType,
      orElse: null,
    );

    return Scaffold(
      key: _scaffoldKey,
      appBar: DefaultAppBar(title: context.translation.newServiceReport),
      body: SafeArea(
        child: LoadingManager(
          isLoading: _isLoading,
          isFailedLoading: false,
          stateCode: 200,
          onRefresh: () async {},
          child: Form(
            key: _formKey,
            child: Column(
              children: [
                SingleChildScrollView(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      Card(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            widget.request.hospitalName!.heading5(context),
                            8.height,
                            "${context.translation.assetNo}: ${widget.request.deviceNumber}".bodyText(context),
                            "${context.translation.callId}: ${widget.request.requestCode}".bodyText(context),
                          ],
                        ).paddingAll(16),
                      ),
                      8.height,
                      ADatePicker(
                        label: context.translation.returnToService,
                        date: DateTime.tryParse(_serviceReport.visitDate ?? ""),
                        formatDateWithTime: true,
                        onDatePicker: (selectedDate) {
                          showTimePicker(
                            context: context,
                            initialTime: TimeOfDay.now(),
                          ).then((selectedTime) {
                            if (selectedTime != null) {
                              DateTime selectedDateTime = DateTime(
                                selectedDate.year,
                                selectedDate.month,
                                selectedDate.day,
                                selectedTime.hour,
                                selectedTime.minute,
                              );
                              if (selectedDateTime.isBefore(DateTime.parse(widget.request.date!))) {
                                "Return to service Date time must be greater then request date".showToast;
                                return;
                              }
                              setState(() {
                                _serviceReport.visitDate = selectedDateTime.toIso8601String();
                              });
                            }
                          });
                        },
                      ),
                      8.height,
                      AppTimer(
                        label: context.translation.workingHours,
                        timer: _serviceReport.timer,
                        enabled: _serviceReport.endofWorkTime == null,
                        onPick: (value) {},
                        onChange: (timer) async {
                          _serviceReport.timer = timer;
                          if (timer.startAt != null && timer.endAt != null) {
                            if (timer.durationInSecond != 0) {
                              _serviceReport.workingHours = num.tryParse((((timer.durationInSecond ?? 0) / 60) / 60).toStringAsFixed(2) ?? "0");
                            } else {
                              timer.durationInSecond = (timer.endAt!.difference(timer.startAt!)).inSeconds;
                              String workingHours = (((timer.durationInSecond ?? 0) / 60) / 60).toStringAsFixed(2);
                              _serviceReport.workingHours = num.tryParse(workingHours ?? "0");
                            }
                          }
                          return true;
                        },
                      ),
                      8.height,
                      LoadingManager(
                        isLoading: _assetTypeProvider.isLoading,
                        isFailedLoading: _assetTypeProvider.statuses == null,
                        stateCode: _assetTypeProvider.stateCode,
                        onRefresh: () async {
                          _assetTypeProvider.reset();
                          await _assetTypeProvider.getTypes();
                          _serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere(
                            (element) => element.value == _serviceReport.callRequest!.assetType,
                            orElse: null,
                          );
                        },
                        child: AppTextFormField(
                          labelText: context.translation.assetType,
                          initialValue: _serviceReport.assetType?.name,
                          textAlign: TextAlign.center,
                          enable: false,
                          style: Theme.of(context).textTheme.titleMedium,
                        ),
                      ),
                      8.height,
                      SingleItemDropDownMenu<Lookup, EquipmentStatusProvider>(
                        context: context,
                        title: context.translation.equipmentStatus,
                        initialValue: _serviceReport.equipmentStatus,
                        onSelect: (value) {
                          if (value != null) {
                            _serviceReport.equipmentStatus = value;
                          }
                        },
                      ),
                      8.height,
                      SingleItemDropDownMenu<Lookup, ReasonProvider>(
                        context: context,
                        title: context.translation.reason,
                        initialValue: _serviceReport.reason,
                        onSelect: (value) {
                          _serviceReport.reason = value;
                        },
                      ),
                      8.height,
                      SingleItemDropDownMenu<Lookup, ServiceTypeProvider>(
                        context: context,
                        title: context.translation.serviceType,
                        initialValue: _serviceReport.serviceType,
                        onSelect: (value) {
                          _serviceReport.serviceType = value;
                        },
                      ),
                      8.height,
                      ServiceReportLastCallsMenu(
                        report: _serviceReport,
                        title: context.translation.callLastSituation,
                        parentId: "0", //widget.request.id,
                        onSelect: (status) {
                          _serviceReport.calllastSituation = status;
                        },
                      ),
                      8.height,
                      ServiceReportFaultDescription(
                        requestId: widget.request.id,
                        initialValue: _serviceReport.faultDescription,
                        onSelect: (status) {
                          _serviceReport.faultDescription = status;
                          _workPreformedController.text = _serviceReport.faultDescription?.workPerformed ?? "";
                        },
                      ),
                      8.height,
                      AppTextFormField(
                        labelText: context.translation.solution,
                        initialValue: _serviceReport.faultDescription?.workPerformed,
                        textAlign: TextAlign.center,
                        enable: false,
                        controller: _workPreformedController,
                      ),
                      8.height,
                      SingleItemDropDownMenu<Lookup, LoanAvailabilityProvider>(
                        context: context,
                        title: context.translation.loanAvailability,
                        initialValue: _serviceReport.loanAvailablity,
                        onSelect: (status) {
                          if (status != null) {
                            setState(() {
                              _serviceReport.loanAvailablity = status;
                              if (_serviceReport.loanAvailablity!.value != 1) {
                                loanAvailabilityAsset = null;
                                _serviceReport.assetLoan = null;
                              }
                            });
                          }
                        },
                      ),
                      if (_serviceReport.loanAvailablity?.value == 1) 8.height,
                      if (_serviceReport.loanAvailablity?.value == 1)
                        PickAsset(
                          device: loanAvailabilityAsset, // ?? _serviceReport.device,
                          onPickAsset: (asset) {
                            _serviceReport.assetLoan = AssetInfo.fromJson(asset.toJson());
                            setState(() {
                              loanAvailabilityAsset = asset;
                            });
                          },
                        ),
                      8.height,
                      ServiceReportAssistantEmployeeMenu(
                        title: context.translation.assignAssistant,
                        assetId: _serviceReport.callRequest!.asset!.id!,
                        initialValue: (_serviceReport.assistantEmployees?.isNotEmpty ?? false) ? _serviceReport.assistantEmployees?.first : null,
                        onSelect: (employee) {
                          if (employee == null) {
                            _serviceReport.assistantEmployees = [];
                          } else {
                            _serviceReport.assistantEmployees = [employee.copyWith(id: 0)];
                          }
                        },
                      ),
                      8.height,
                      AppTextFormField(
                        labelText: context.translation.travelingExpense,
                        initialValue: _serviceReport.travelingExpenses?.toString(),
                        textInputType: const TextInputType.numberWithOptions(decimal: true),
                        onSaved: (value) {
                          _serviceReport.travelingExpenses = double.tryParse(value) ?? 0.0;
                        },
                      ),
                      8.height,
                      AppTextFormField(
                        labelText: context.translation.travelingHours,
                        initialValue: _serviceReport.travelingHours?.toString(),
                        textInputType: const TextInputType.numberWithOptions(decimal: true),
                        onSaved: (value) {
                          _serviceReport.travelingHours = double.tryParse(value) ?? 0.0;
                        },
                      ),
                      8.height,
                      AppTextFormField(
                        initialValue: _serviceReport.comment,
                        labelText: context.translation.technicalComment,
                        alignLabelWithHint: true,
                        textInputType: TextInputType.multiline,
                        onSaved: (value) {
                          _serviceReport.comment = value;
                        },
                      ),
                      8.height,
                      ServiceReportRepairLocation(
                        label: context.translation.repairLocation,
                        initialValue: _serviceReport.repairLocation,
                        onSelect: (status) {
                          _serviceReport.repairLocation = status;
                        },
                      ),
                      8.height,
                      PartNoButton(
                        controller: _partQtyController,
                        spareParts: _spareParts,
                        initialList: _serviceReport.sparePartsWorkOrders,
                        onChange: (parts) {
                          _serviceReport.sparePartsWorkOrders = parts;
                        },
                      ),
                      8.height,
                      AttachmentPicker(label: context.translation.attachImage, attachment: attachments),
                      8.height,
                      ESignature(
                        title: context.translation.engSign,
                        oldSignature: _serviceReport.engSignature,
                        newSignature: _serviceReport.localEngSignature,
                        onSaved: (signature) {
                          // if (signature == null || signature.isEmpty) {
                          //   setState(() {});
                          //   return;
                          // }
                          if (signature == null || signature.isEmpty) return;
                          _serviceReport.localEngSignature = signature;
                          _serviceReport.engSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null;
                        },
                      ),
                      8.height,
                      ESignature(
                        title: context.translation.nurseSignature,
                        oldSignature: _serviceReport.nurseSignature,
                        newSignature: _serviceReport.localNurseSignature,
                        onSaved: (signature) {
                          // if (signature == null || signature.isEmpty) {
                          //   setState(() {});
                          //   return;
                          // }
                          if (signature == null || signature.isEmpty) return;
                          _serviceReport.localNurseSignature = signature;
                          _serviceReport.nurseSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null;
                        },
                      ),
                      24.height,
                    ],
                  ),
                ).expanded,
                AppFilledButton(
                  label: context.translation.submitRequest,
                  onPressed: () async {
                    if ((!_formKey.currentState!.validate()) || (!(await _serviceReport.validate(context)))) {
                      setState(() {});
                      return;
                    }
                    _formKey.currentState!.save();
                    _serviceReport.attachmentsWorkOrder ??= [];
                    if (attachments.isEmpty) _serviceReport.attachmentsWorkOrder = [];
                    for (var item in attachments) {
                      String fileName = ServiceRequestUtils.isLocalUrl(item.name??'') ? ("${item.name??''.split("/").last}|${base64Encode(File(item.name??'').readAsBytesSync())}") :item.name??'';
                      _serviceReport.attachmentsWorkOrder!.add(Attachment(id: item.id, name: fileName));
                    }
                    final user = Provider.of<UserProvider>(context, listen: false).user!;
                    await _serviceRequestsProvider.createServiceReport(context, report: _serviceReport, request: widget.request, user: user);
                  },
                ),
              ],
            ).paddingAll(16),
          ),
        ),
      ),
    );
  }
}
