import 'dart:convert';

import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_pos_printer_platform_image_3/flutter_pos_printer_platform_image_3.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:ticket_booth/app/print_ticket.dart';
import 'package:ticket_booth/app/route.dart';
import 'package:ticket_booth/model/booth.dart';
import 'package:ticket_booth/model/branch_model.dart';
import 'package:ticket_booth/model/cabapility_model.dart';
import 'package:ticket_booth/model/layanan.dart';
import 'package:ticket_booth/model/printer_device.dart';
import 'package:ticket_booth/provider/all_service_provider.dart';
import 'package:ticket_booth/screen/settings/booth_list_provider.dart';
import 'package:ticket_booth/screen/settings/branch_list_provider.dart';
import 'package:ticket_booth/screen/settings/service_list_provider.dart';

import '../../app/constant.dart';
import '../widgets/error_dialog.dart';
import 'form_input.dart';

class SettingScreen extends HookConsumerWidget {
  const SettingScreen({super.key});
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final hostIpController = useTextEditingController(text: '');
    final hostQrController = useTextEditingController(text: '');
    final headerDisplayController = useTextEditingController(text: '');
    final footerDisplayController = useTextEditingController(text: '');
    final footerTicketController = useTextEditingController(text: '');
    final headerTicketController = useTextEditingController(text: '');
    final activeLayanan = useState<List>(List.empty());
    final capabilityProfileList = useState<List<CapabilityProfileModel>>([]);
    final selectedCapabilityProfile = useState<CapabilityProfileModel?>(null);
    final isLoading = useState(false);
    final data = useState('N');
    final PrinterManager pm = PrinterManager.instance;
    final dvcs = useState<List<PrinterDev>>([]);
    var devices3 = <PrinterDev>[];
    final selectedBtnSize = useState<Map<String, dynamic>>({
      'name': '4',
      'message': 'Tombol yang akan ditampilkan berjumlah 4 ',
      'rightLeftWidth': "300",
      'centerWidth': "912",
      'childAspectRatio': '1.559',
      'mainAxisSpacing': "10",
      'crossAxisSpacing': '10',
      'btnHeight': "330",
      'btnWidth': '300',
      'column': '2'
    });
    final List<Map<String, dynamic>> listBtnSize = [
      {
        'name': '10',
        'message': 'Tombol yang akan ditampilkan berjumlah 10',
        'rightLeftWidth': "40",
        'centerWidth': "1432",
        'childAspectRatio': '1',
        'mainAxisSpacing': "20",
        'crossAxisSpacing': '10',
        'btnHeight': "290",
        'btnWidth': '260',
        'column': '5'
      },
      {
        'name': '8',
        'message': 'Tombol yang akan ditampilkan berjumlah 8 ',
        'rightLeftWidth': "100",
        'centerWidth': "1312",
        'childAspectRatio': '1.1',
        'mainAxisSpacing': "40",
        'crossAxisSpacing': '10',
        'btnHeight': "310",
        'btnWidth': '280',
        'column': '4'
      },
      {
        'name': '6',
        'message': 'Tombol yang akan ditampilkan berjumlah 6 ',
        'rightLeftWidth': "200",
        'centerWidth': "1112",
        'childAspectRatio': '1.33',
        'mainAxisSpacing': "40",
        'crossAxisSpacing': '10',
        'btnHeight': "310",
        'btnWidth': '280',
        'column': '3'
      },
      {
        'name': '4',
        'message': 'Tombol yang akan ditampilkan berjumlah 4 ',
        'rightLeftWidth': "300",
        'centerWidth': "912",
        'childAspectRatio': '1.559',
        'mainAxisSpacing': "10",
        'crossAxisSpacing': '10',
        'btnHeight': "330",
        'btnWidth': '300',
        'column': '2'
      }
    ];
    getServiceBooth() async {
      activeLayanan.value = List.empty();
      ref.read(BoothListProvider.notifier).list(hostIp: hostIpController.text);
      ref
          .read(ServiceListProvider.notifier)
          .list(hostIp: hostIpController.text);
      ref.read(BranchListProvider.notifier).list(hostIp: hostIpController.text);
    }

    _scan(PrinterType type) async {
      // Find printers
      pm.discovery(type: PrinterType.usb, isBle: false).listen((device) {
        devices3.add(PrinterDev(
          id: int.parse(device.productId ?? '0'),
          deviceName: device.name,
          address: device.address,
          isBle: false,
          vendorId: device.vendorId,
          productId: device.productId,
        ));
      });
    }

    full() async {
      // await FullScreen.enterFullScreen(FullScreenMode.EMERSIVE_STICKY);
    }
    final lyn = useState<List<Layanan>>(List.empty());

    final booth = useState<List<Booth>>(List.empty());
    final branch = useState<List<BranchModel>>(List.empty());
    final selected_printer = useState<PrinterDev?>(null);
    final selected_booth =
        useState<Booth>(Booth(name: 'Pilih salah satu', id: 0, code: 'b1'));
    final selected_branch = useState<BranchModel>(
        BranchModel(mBranchID: '0', mBranchName: 'Pilih salah satu cabang'));
    Future delData() async {
      // Obtain shared preferences.
      try {
        final prefs = await SharedPreferences.getInstance();
        await prefs.remove('tb-westerindo');
      } catch (e) {
        print(e);
      }
    }

    Future getData() async {
      try {
        final prefs = await SharedPreferences.getInstance();
        var raw_data = prefs.getString('tb-westerindo') ?? 'a';
        data.value = raw_data;
        print(raw_data);
        if (raw_data != 'a') {
          lyn.value = ref.read(allServiceProvider);
          var data = json.decode(raw_data);
          selected_booth.value = Booth.fromJson(data['selectedBooth']);
          selected_branch.value = BranchModel.fromJson(data['selectedBranch']);
          selected_printer.value = PrinterDev.fromJson(data['selectedPrinter']);
          hostIpController.text = data['hostIp'];
          hostQrController.text = data['hostQrIp'];
          headerDisplayController.text = data['headerDisplay'];
          footerDisplayController.text = data['footerDisplay'];
          footerTicketController.text = data['footerTicket'];
          headerTicketController.text = data['headerTicket'];
          activeLayanan.value = data['activeLayanan'] ?? List.empty();
          selectedBtnSize.value = data['buttonSize'];
          selectedCapabilityProfile.value =
              CapabilityProfileModel.fromJson(data['selectedCapability']);

          if (activeLayanan.value.isNotEmpty) {
            activeLayanan.value.forEach((e) {
              lyn.value.forEach((f) {
                if (e == f.id) {
                  f.value = true;
                }
              });
            });
          }
        }
      } catch (e) {
        print(e);
        ErrorDialog(context, e.toString(), 'ERROR');
      }
    }

    useEffect(() {
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
        await getData();
        var capabilityList = await CapabilityProfile.getAvailableProfiles();
        List<CapabilityProfileModel> cl = List.empty(growable: true);
        for (var i = 0; i < capabilityList.length; i++) {
          var data = capabilityList[i];
          final model = CapabilityProfileModel.fromJson(data);
          cl.add(model);
        }
        capabilityProfileList.value = cl;

        var stb = capabilityProfileList.value.firstWhere(
            (element) => element.key == selectedCapabilityProfile.value?.key,
            orElse: () => CapabilityProfileModel());
        if (stb.key != null) {
          selectedCapabilityProfile.value = stb;
        }

        _scan(PrinterType.usb);
        dvcs.value = devices3;
        if (data.value != 'a') {
          ref
              .read(BoothListProvider.notifier)
              .list(hostIp: hostIpController.text);
          ref
              .read(BranchListProvider.notifier)
              .list(hostIp: hostIpController.text);
        }
      });
      full();
      return () {};
    }, []);
    ref.listen(BoothListProvider, (previous, next) {
      if (next is BoothListStateLoading) {
        isLoading.value = true;
      } else if (next is BoothListStateError) {
        ErrorDialog(context, next.message, 'ERROR');
        isLoading.value = false;
      } else if (next is BoothListStateDone) {
        booth.value = next.model;
        isLoading.value = false;
      }
    });
    ref.listen(ServiceListProvider, (previous, next) {
      if (next is ServiceListStateLoading) {
        isLoading.value = true;
      } else if (next is ServiceListStateError) {
        ErrorDialog(context, next.message, 'ERROR');
        isLoading.value = false;
      } else if (next is ServiceListStateDone) {
        // ref.read(allServiceProvider.notifier).state = next.model;
        // print(ref.read(allServiceProvider));
        lyn.value = next.model;
        isLoading.value = false;
      }
    });
    ref.listen(BranchListProvider, (previous, next) {
      if (next is BranchListStateLoading) {
        isLoading.value = true;
      } else if (next is BranchListStateError) {
        ErrorDialog(context, next.message, 'ERROR');
        isLoading.value = false;
      } else if (next is BranchListStateDone) {
        // ref.read(allServiceProvider.notifier).state = next.model;
        // print(ref.read(allServiceProvider));
        branch.value = next.model;
        isLoading.value = false;
      }
    });
    Future<bool> saveData() async {
      try {
        final prefs = await SharedPreferences.getInstance();
        final Map<String, dynamic> data = {
          "headerDisplay": headerDisplayController.text != ''
              ? headerDisplayController.text
              : 'Selamat Datang Di Pramita',
          "footerDisplay": footerDisplayController.text != ''
              ? footerDisplayController.text
              : 'Sentuh Salah Satu Layanan',
          "footerTicket": footerTicketController.text != ''
              ? footerTicketController.text
              : 'SCAN QR CODE UNTUK MELIHAT STATUS ANTRIAN',
          "headerTicket": headerTicketController.text != ''
              ? headerTicketController.text
              : 'Labratorium Medis & Klinik PRAMITA',
          "hostQrIp": hostQrController.text,
          "hostIp": hostIpController.text,
          "selectedPrinter": selected_printer.value,
          "selectedBooth": selected_booth.value,
          "selectedBranch": selected_branch.value,
          "activeLayanan": activeLayanan.value,
          'buttonSize': selectedBtnSize.value,
          "selectedCapability": selectedCapabilityProfile.value
        };
        json.encode(data);
        await prefs.setString('tb-westerindo', json.encode(data));
        return true;
      } catch (e) {
        ErrorDialog(context, e.toString(), 'ERROR');
        print(e);
        return false;
      }
    }

    Color getColor(Set<MaterialState> states) {
      const Set<MaterialState> interactiveStates = <MaterialState>{
        MaterialState.pressed,
        MaterialState.hovered,
        MaterialState.focused,
      };

      if (states.any(interactiveStates.contains)) {
        return Colors.blue;
      }
      if (states.contains(MaterialState.selected)) {
        return Colors.green;
      }
      return Colors.white;
    }

    return Material(
        child: Container(
      height: Constant.getActualY(context: context, y: 982),
      width: Constant.getActualX(context: context, x: 1512),
      decoration: const BoxDecoration(
          image: DecorationImage(
              fit: BoxFit.cover,
              image: AssetImage("assets/images/new-bg-icon.png"))),
      child: Center(
        child: Card(
          color: Colors.white,
          shadowColor: Colors.white,
          shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(10))),
          elevation: 5,
          child: SizedBox(
            height: Constant.getActualY(context: context, y: 880),
            width: Constant.getActualX(context: context, x: 1360),
            child: Padding(
              padding: EdgeInsets.symmetric(
                  horizontal: Constant.getActualX(context: context, x: 30),
                  vertical: Constant.getActualY(context: context, y: 30)),
              child: SingleChildScrollView(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      children: [
                        // TextButton(
                        //     onPressed: () {
                        //       Navigator.of(context)
                        //           .popAndPushNamed(displayRoute);
                        //       // print(pm.currentStatusUSB);
                        //       // print(pm.currentStatusUSB);
                        //     },
                        //     child: const Text('back')),
                        Text(
                          'Setting',
                          style: Constant.subTitle(context: context),
                        ),
                        // TextButton(
                        //     onPressed: () {
                        //       delData();
                        //     },
                        //     child: const Text('Delete All')),
                      ],
                    ),
                    SizedBox(
                      height: Constant.getActualY(context: context, y: 30),
                    ),
                    FormInput(
                        pm: pm,
                        selected_booth: selected_booth,
                        booth: booth,
                        selected_printer: selected_printer,
                        prnt: dvcs,
                        branch: branch,
                        selected_branch: selected_branch,
                        hostIpController: hostIpController,
                        hostQrController: hostQrController,
                        headerDisplayController: headerDisplayController,
                        footerDisplayController: footerDisplayController,
                        headerTicketController: headerTicketController,
                        getServiceBooth: getServiceBooth,
                        isLoading: isLoading.value,
                        selectedCapability: selectedCapabilityProfile,
                        capabilityList: capabilityProfileList,
                        footerTicketController: footerTicketController),
                    SizedBox(
                      height: Constant.getActualY(context: context, y: 20),
                    ),
                    Container(
                      // color: Colors.red,
                      height: Constant.getActualY(context: context, y: 40),
                      child: Row(
                        children: [
                          Tooltip(
                            message: "Jumlah tombol pada display",
                            child: Text('Button display',
                                style: Constant.label(context: context)),
                          ),
                          SizedBox(
                            width: Constant.getActualX(context: context, x: 10),
                          ),
                          Row(
                            children: [
                              SizedBox(
                                width: Constant.getActualX(
                                    context: context, x: 10),
                              ),
                              Row(
                                children: listBtnSize
                                    .map(
                                      (e) => Row(
                                        children: [
                                          Checkbox(
                                              fillColor: MaterialStateProperty
                                                  .resolveWith(getColor),
                                              value: e['name'].toString() ==
                                                      selectedBtnSize
                                                          .value['name']
                                                  ? true
                                                  : false,
                                              onChanged: ((value) {
                                                selectedBtnSize.value = e;
                                              })),
                                          SizedBox(
                                            width: Constant.getActualX(
                                                context: context, x: 3),
                                          ),
                                          Tooltip(
                                            message: e['message'].toString(),
                                            child: Text(
                                              e['name'].toString(),
                                              style: Constant.normal(
                                                  context: context),
                                            ),
                                          ),
                                          SizedBox(
                                            width: Constant.getActualX(
                                                context: context, x: 15),
                                          ),
                                        ],
                                      ),
                                    )
                                    .toList(),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    SizedBox(
                      height: Constant.getActualY(context: context, y: 190),
                      child: GridView.count(
                          childAspectRatio:
                              Constant.getActualY(context: context, y: 150) /
                                  Constant.getActualX(context: context, x: 15),
                          crossAxisCount: 3,
                          children: lyn.value
                              .map((e) => Row(
                                    children: [
                                      Transform.scale(
                                        scale: 0.8,
                                        child: CupertinoSwitch(
                                            value: e.value,
                                            onChanged: (val) {
                                              if (val) {
                                                var rw_data = json.encode(
                                                    activeLayanan.value);
                                                List data =
                                                    json.decode(rw_data);
                                                List actlyn = data;
                                                actlyn.add(e.id);
                                                activeLayanan.value = actlyn;
                                              }
                                              if (!val) {
                                                var rw_data = json.encode(
                                                    activeLayanan.value);
                                                List data =
                                                    json.decode(rw_data);
                                                List actlyn = data;
                                                actlyn.remove(e.id);
                                                activeLayanan.value = actlyn;
                                              }

                                              e.value = val;
                                            }),
                                      ),
                                      Expanded(
                                        child: e.isConsultDoctor == 'N'
                                            ? Text(
                                                e.name,
                                                maxLines: 2,
                                                overflow: TextOverflow.ellipsis,
                                                style: Constant.normal(
                                                    context: context),
                                              )
                                            : Text(
                                                "${e.name} ${e.doctorName}",
                                                maxLines: 2,
                                                overflow: TextOverflow.ellipsis,
                                                style: Constant.normal(
                                                    context: context),
                                              ),
                                      )
                                    ],
                                  ))
                              .toList()),
                    ),
                    SizedBox(
                      height: Constant.getActualY(context: context, y: 20),
                    ),
                    Center(
                      child: SizedBox(
                          height: Constant.getActualY(context: context, y: 60),
                          width: Constant.getActualX(context: context, x: 200),
                          child: ElevatedButton(
                            onPressed: () {
                              if (selected_booth.value != null &&
                                  selected_booth.value.id > 0 &&
                                  selected_printer.value != null &&
                                  selectedCapabilityProfile.value?.key !=
                                      null &&
                                  selected_branch.value != null &&
                                  selected_branch.value.mBranchID != '0' &&
                                  hostIpController.text.isNotEmpty &&
                                  activeLayanan.value.isNotEmpty) {
                                saveData();
                                ref.read(allServiceProvider.notifier).state =
                                    lyn.value;
                                Navigator.of(context).pushNamed(queueRoute);
                              } else {
                                if (selected_booth.value == null ||
                                    selected_printer.value == null ||
                                    selectedCapabilityProfile.value == null ||
                                    hostIpController.text.isEmpty) {
                                  ErrorDialog(
                                      context,
                                      'Input bertanda * tidak boleh kosong',
                                      'PERINGATAN');
                                } else if (activeLayanan.value.isEmpty) {
                                  ErrorDialog(
                                      context,
                                      'Layanan belum ada yang aktif',
                                      'PERINGATAN');
                                }
                              }
                            },
                            style: ElevatedButton.styleFrom(
                                elevation: 5, backgroundColor: Colors.blue),
                            child: Text(
                              'Save',
                              style: Constant.subTitle(context: context)
                                  .copyWith(color: Colors.white),
                            ),
                          )),
                    )
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    ));
  }
}
