import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:garage/car/model/service_comment.dart';
import 'package:garage/car/model/tyre_type.dart';
import 'package:garage/car/widget/add_edit_text_field.dart';
import 'package:garage/car/widget/date_picker_button.dart';
import 'package:garage/car/widget/tyre_picker.dart';
import 'package:garage/insurance/model/currency.dart';
import 'package:garage/insurance/widget/currency_picker.dart';
import 'package:garage/insurance/widget/insurance_row.dart';
import 'package:garage/user/model/user_provider.dart';
import 'package:garage/utils/color_utils.dart';
import 'package:garage/utils/show_ok_dialog.dart';
import 'package:get_it/get_it.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';

import '../../insurance/model/insurance.dart';
import '../../utils/date_time_utils.dart';
import '../model/car.dart';
import '../service/car_service.dart';

class InfoCarPage extends StatefulWidget {
  final Car car;
  final VoidCallback refresh;
  final bool isArchived;

  const InfoCarPage({
    super.key,
    required this.car,
    required this.refresh,
    this.isArchived = false,
  });

  @override
  State<InfoCarPage> createState() => _InfoCarPageState();
}

class _InfoCarPageState extends State<InfoCarPage> {
  late Car currentCar = widget.car;
  late Insurance? insurance = widget.car.getCurrentInsurance();
  final CarService carService = GetIt.instance<CarService>();
  final GlobalKey<FormState> editFormKey = GlobalKey<FormState>();
  final TextEditingController newCommentController = TextEditingController();
  DateTime? newCommentDate = DateTime.now();
  late List<DateTime?> serviceDates = [
    for (ServiceComment serv in currentCar.serviceBook) serv.date
  ];
  late List<TextEditingController> serviceCons = [
    for (ServiceComment serv in currentCar.serviceBook)
      TextEditingController(text: serv.message)
  ];
  bool editing = false;
  late bool withInsurance = insurance != null;

  late final List<TextEditingController> carCons = [
    TextEditingController(text: currentCar.name),
    TextEditingController(text: currentCar.brand),
    TextEditingController(text: currentCar.model),
    TextEditingController(text: currentCar.spz),
  ];
  late final List<TextEditingController> insuranceCons = [
    TextEditingController(text: insurance?.contractNumber),
    TextEditingController(text: insurance?.company),
    TextEditingController(text: insurance?.amount.toString()),
  ];
  late TyreType _tyreType = currentCar.tyreType;
  late DateTime? _expirationInsurance = insurance?.expirationDate;
  late Currency? _currency = insurance?.currency;
  File? newPhoto;
  bool removePhoto = false;
  bool hasImage = true;
  late DateTime? _tollExpiration = currentCar.tollExpiration;
  late DateTime? _expirationSTK = currentCar.getCurrentSTK();
  int index = 0;

  @override
  Widget build(BuildContext context) {
    final UserProvider provider = context.read<UserProvider>();
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        centerTitle: true,
        title: Text(
          currentCar.name,
          style: TextStyle(fontWeight: FontWeight.bold),
        ),
        actions: editing == false
            ? [
                IconButton(
                    onPressed: () {
                      setState(() {
                        editing = true;
                      });
                    },
                    icon: Icon(
                      Icons.edit,
                      color: Colors.black,
                    )),
                IconButton(
                    onPressed: () => showDialog<String>(
                          context: context,
                          builder: (BuildContext context) => AlertDialog(
                            title: Text(widget.isArchived
                                ? "Chce vrátit vozidlo zpět do aktivní flotily?"
                                : "Vážně chcete archivovat toto vozidlo?"),
                            content: Text(widget.isArchived
                                ? "Vozidlo '${currentCar.name}' bude uvedeno do aktivní flotily."
                                : "Vozidlo '${currentCar.name}' bude archivováno."),
                            actions: <Widget>[
                              TextButton(
                                onPressed: () => Navigator.pop(context),
                                child: const Text('Zrušit'),
                              ),
                              TextButton(
                                onPressed: () {
                                  provider.archiveCar(currentCar.id!);
                                  Navigator.pop(context);
                                  Navigator.pop(context);
                                },
                                child: Text(widget.isArchived
                                    ? "Aktivovat"
                                    : 'Archivovat'),
                              ),
                            ],
                          ),
                        ),
                    icon: Icon(
                      Icons.archive_rounded,
                      color: Colors.black,
                    )),
                IconButton(
                    onPressed: () => showDialog<String>(
                          context: context,
                          builder: (BuildContext context) => AlertDialog(
                            title:
                                const Text("Vážně chcete smazat toto vozidlo?"),
                            content: Text(
                                "Vozidlo '${currentCar.name}' bude smazáno navždy!"),
                            actions: <Widget>[
                              TextButton(
                                onPressed: () => Navigator.pop(context),
                                child: const Text('Zrušit'),
                              ),
                              TextButton(
                                onPressed: () {
                                  provider.removeCar(currentCar.id!, hasImage);
                                  Navigator.pop(context);
                                  Navigator.pop(context);
                                },
                                child: const Text('Smazat'),
                              ),
                            ],
                          ),
                        ),
                    icon: Icon(
                      Icons.delete,
                      color: Colors.redAccent,
                    )),
              ]
            : [
                IconButton(
                    onPressed: () {
                      _updateCar();
                    },
                    icon: Icon(Icons.done)),
                IconButton(
                    onPressed: () {
                      setState(() {
                        _expirationSTK = currentCar.getCurrentSTK();
                        newPhoto = null;
                        removePhoto = false;
                        editing = false;
                        serviceDates = [
                          for (ServiceComment serv in currentCar.serviceBook)
                            serv.date
                        ];
                        serviceCons = [
                          for (ServiceComment serv in currentCar.serviceBook)
                            TextEditingController(text: serv.message)
                        ];
                      });
                    },
                    icon: Icon(Icons.cancel))
              ],
      ),
      body: Form(
        key: editFormKey,
        autovalidateMode: AutovalidateMode.disabled,
        child: ListView(children: [
          Padding(
              padding:
                  const EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0),
              child: Container(
                height: 200,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.all(Radius.circular(20)),
                ),
                child: Stack(
                  children: <Widget>[
                    Center(
                      child: newPhoto == null
                          ? removePhoto
                              ? Image.asset('images/empty.jpg')
                              : _createNetworkImage()
                          : Image.file(newPhoto!),
                    ),
                    if (editing && !removePhoto && hasImage)
                      Positioned(
                        right: -10,
                        top: -10,
                        child: IconButton(
                            color: Colors.red,
                            onPressed: () {
                              if (newPhoto == null) {
                                setState(() {
                                  removePhoto = true;
                                });
                              } else {
                                setState(() {
                                  newPhoto = null;
                                });
                              }
                            },
                            icon: Icon(Icons.highlight_remove_rounded)),
                      )
                  ],
                ),
              )),
          if (editing)
            ElevatedButton(
                onPressed: _selectImage, child: Text("Změnit fotku")),
          _buildCarDescription(),
          if (insurance != null || editing)
            Row(
              children: [
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.only(left: 8.0),
                    child: Text(
                      "Pojištění",
                      style: TextStyle(fontSize: 25),
                    ),
                  ),
                ),
                if (insurance == null)
                  Switch(
                      value: withInsurance,
                      onChanged: (value) {
                        setState(() {
                          withInsurance = !withInsurance;
                        });
                      }),
              ],
            ),
          if (insurance != null) _buildInsurance(),
          if (insurance == null && editing && withInsurance) _buildInsurance(),
          _buildSwitchers(),
          switch (index) {
            0 => _buildServiceBook(),
            1 => _buildInsuranceRecords(),
            2 => _buildSTK(),
            int() => Text("Error"),
          }
        ]),
      ),
    );
  }

  Widget _buildSwitchers() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Spacer(),
        _buildTabButton(() => setState(() => index = 0), "Servisní kniha", 0),
        Spacer(),
        _buildTabButton(() => setState(() => index = 1), "Pojištění", 1),
        Spacer(),
        _buildTabButton(() => setState(() => index = 2), "STK", 2),
        Spacer(),
      ],
    );
  }

  Widget _buildTabButton(VoidCallback onPressed, String text, int buttonIndex) {
    return TextButton(
      style: TextButton.styleFrom(
        shape: ContinuousRectangleBorder(),
        foregroundColor: Colors.white,
        backgroundColor: buttonIndex == index
            ? Theme.of(context).colorScheme.primary
            : Colors.grey,
        padding: const EdgeInsets.fromLTRB(21, 5, 21, 5),
        textStyle: const TextStyle(fontSize: 20),
      ),
      onPressed: onPressed,
      child: Text(text),
    );
  }

  Widget _buildServiceBook() {
    if (currentCar.serviceBook.isEmpty && !editing) {
      return Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          Text("Žádný záznam v servisní knize"),
          TextButton(
              onPressed: () => setState(() => editing = true),
              child: Text("Přidat záznam"))
        ]),
      );
    }
    return Column(
      children: [
        if (editing) _buildNewServiceComment(),
        for (final (i, con) in serviceCons.indexed)
          _buildBox(
              Row(
                children: [
                  !editing
                      ? Expanded(
                          child: Text(
                              getPrettyDate(currentCar.serviceBook[i].date),
                              textAlign: TextAlign.end),
                        )
                      : Expanded(
                          flex: 3,
                          child: DatePickerButton(
                              date: serviceDates[i],
                              onSave: (date) =>
                                  setState(() => serviceDates[i] = date)),
                        ),
                  !editing
                      ? Expanded(
                          flex: 8,
                          child: Padding(
                            padding: const EdgeInsets.only(left: 8.0),
                            child: Text(currentCar.serviceBook[i].message),
                          ))
                      : Expanded(flex: 10, child: TextField(controller: con)),
                  if (editing)
                    IconButton(
                        onPressed: () => setState(() {
                              serviceDates.removeAt(i);
                              serviceCons.removeAt(i);
                            }),
                        icon: Icon(
                          Icons.delete,
                          color: Colors.red,
                        ))
                ],
              ),
              Theme.of(context).colorScheme.inversePrimary)
      ],
    );
  }

  Widget _buildNewServiceComment() {
    return _buildBox(
        Row(
          children: [
            Expanded(
              flex: 30,
              child: DatePickerButton(
                  date: newCommentDate,
                  onSave: (date) => setState(() => newCommentDate = date)),
            ),
            Expanded(
                flex: 120, child: TextField(controller: newCommentController)),
          ],
        ),
        Theme.of(context).colorScheme.inversePrimary);
  }

  Widget _buildInsuranceRecords() {
    if (currentCar.insurances.isEmpty) {
      return Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          Text("Žádné pojištění neevidováno"),
          TextButton(
              onPressed: () => setState(() {
                    editing = true;
                    withInsurance = true;
                  }),
              child: Text("Přidat pojištění"))
        ]),
      );
    }
    return Column(
      children: [
        for (Insurance ins in currentCar.insurances.reversed)
          InsuranceRow(insurance: ins)
      ],
    );
  }

  Widget _buildSTK() {
    return Column(
      children: [
        for (DateTime date in currentCar.stkExpirations.reversed)
          _buildBox(
              Center(child: Text(getPrettyDate(date))), Colors.orangeAccent),
      ],
    );
  }

  Widget _createNetworkImage() {
    if (!hasImage) {
      return Image.asset('images/empty.jpg');
    }
    return Image.network(
      "https://firebasestorage.googleapis.com/v0/b/garage-pata.appspot.com/o/car_images%2F${currentCar.id!}_car.jpg?alt=media&token=41474050-b327-4f94-95be-30bc2e57f6ea",
      loadingBuilder: (BuildContext context, Widget child,
          ImageChunkEvent? loadingProgress) {
        if (loadingProgress == null) return child;
        return CircularProgressIndicator();
      },
      errorBuilder: (_, __, ___) {
        hasImage = false;
        return Image.asset('images/empty.jpg');
      },
      fit: BoxFit.fitHeight,
    );
  }

  Future<void> _updateCar() async {
    if (!editFormKey.currentState!.validate()) {
      return;
    }
    if (_expirationSTK == null) {
      showOkDialog(context, "Chybí datum expirace STK");
      return;
    }
    if ((insurance != null || withInsurance) && _expirationInsurance == null) {
      showOkDialog(context, "Chybí datum expirace pojištění");
      return;
    }
    List<Insurance> newInsurances = [];
    if (insurance != null || withInsurance) {
      final newInsurance = Insurance(
          company: insuranceCons[1].text,
          contractNumber: insuranceCons[0].text,
          amount: int.parse(insuranceCons[2].text),
          currency: _currency!,
          expirationDate: _expirationInsurance!);
      if (insurance == null) {
        currentCar.insurances.add(newInsurance);
      } else {
        currentCar.insurances[currentCar.insurances.length - 1] = newInsurance;
      }
      newInsurances = currentCar.insurances;
    }
    currentCar.stkExpirations[currentCar.stkExpirations.length - 1] =
        _expirationSTK!;

    final List<ServiceComment> newServiceBook = [];
    for (int i = 0; i < serviceCons.length; i++) {
      if (serviceDates[i] == null) {
        showOkDialog(context, "Chybí datum v servisní knize!");
        return;
      }
      newServiceBook.add(
          ServiceComment(date: serviceDates[i]!, message: serviceCons[i].text));
    }

    if (newCommentController.text.isNotEmpty) {
      if (newCommentDate == null) {
        showOkDialog(context, "Chybí datum servisního záznamu!");
        return;
      }
      newServiceBook.add(ServiceComment(
          date: newCommentDate!, message: newCommentController.text));
    }
    mergeSort(newServiceBook);

    final car = Car(
      id: currentCar.id,
      insurances: newInsurances,
      spz: carCons[3].text,
      brand: carCons[1].text,
      name: carCons[0].text,
      model: carCons[2].text,
      tyreType: _tyreType,
      tollExpiration: _tollExpiration,
      stkExpirations: currentCar.stkExpirations,
      serviceBook: newServiceBook,
    );
    carService.updateItem(car);
    if (removePhoto && hasImage) {
      print("Removing photo from Firebase");
      hasImage = false;
      carService.deletePhoto(currentCar.id!);
    }
    if (newPhoto != null) {
      print("Updating photo to Firebase");
      await carService.updatePhoto(newPhoto, currentCar.id!);
    }
    // This updates whole page
    setState(() {
      currentCar = car;
      insurance = car.getCurrentInsurance();
      editing = false;
      removePhoto = false;
      newPhoto = null;
      newCommentController.clear();
      newCommentDate = DateTime.now();
      serviceDates = [
        for (ServiceComment serv in currentCar.serviceBook) serv.date
      ];
      serviceCons = [
        for (ServiceComment serv in currentCar.serviceBook)
          TextEditingController(text: serv.message)
      ];
    });
    setState(() {});
    widget.refresh();
  }

  Future _selectImage() async {
    final returnedImage =
        await ImagePicker().pickImage(source: ImageSource.gallery);
    if (returnedImage == null) {
      return;
    }
    setState(() {
      newPhoto = File(returnedImage.path);
      hasImage = true;
    });
  }

  Widget _buildCarDescription() {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        children: [
          if (currentCar.name.isNotEmpty || editing)
            _buildInfoRow(
                "Název vozidla",
                currentCar.name,
                () => _buildFormField(
                    carCons[0],
                    (val) =>
                        (val == null || val.isEmpty) ? "Povinné pole" : null)),
          if (currentCar.name.isNotEmpty || editing) Divider(),
          if (currentCar.spz.isNotEmpty || editing)
            _buildInfoRow(
                "SPZ", currentCar.spz, () => _buildFormField(carCons[3])),
          if (currentCar.spz.isNotEmpty || editing) Divider(),
          if (currentCar.brand.isNotEmpty || editing)
            _buildInfoRow(
                "Výrobce", currentCar.brand, () => _buildFormField(carCons[1])),
          if (currentCar.brand.isNotEmpty || editing) Divider(),
          if (currentCar.model.isNotEmpty || editing)
            _buildInfoRow(
                "Model", currentCar.model, () => _buildFormField(carCons[2])),
          if (currentCar.model.isNotEmpty || editing) Divider(),
          _buildInfoRow(
            "Expirace STK",
            getPrettyDate(currentCar.getCurrentSTK()),
            () => DatePickerButton(
                date: _expirationSTK,
                onSave: (date) => setState(() => _expirationSTK = date)),
            getStyledDateAsText(context, currentCar.getCurrentSTK()),
          ),
          Divider(),
          if (currentCar.tollExpiration != null || editing)
            _buildInfoRow(
              "Expirace dálniční známky",
              getPrettyDate(currentCar.tollExpiration),
              () => DatePickerButton(
                  date: currentCar.tollExpiration,
                  onSave: (date) => setState(() => _tollExpiration = date)),
              getStyledDateAsText(context, currentCar.tollExpiration),
            ),
          if (currentCar.tollExpiration != null || editing) Divider(),
          _buildInfoRow(
              "Druh pneumatik",
              currentCar.tyreType.string,
              () => TyrePicker(
                    onChanged: (t) => setState(() => _tyreType = t!),
                    initialValue: _tyreType,
                  )),
          Divider(),
        ],
      ),
    );
  }

  Widget _buildInsurance() {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        children: [
          _buildInfoRow("Číslo smlouvy", insurance?.contractNumber,
              () => _buildFormField(insuranceCons[0])),
          Divider(),
          _buildInfoRow("Společnost", insurance?.company,
              () => _buildFormField(insuranceCons[1])),
          Divider(),
          _buildInfoRow(
              "Cena",
              "${insurance?.amount} ${insurance?.currency.symbol}",
              _buildPriceEditRow),
          Divider(),
          _buildInfoRow(
              "Expirace",
              getPrettyDate(insurance?.expirationDate),
              () => DatePickerButton(
                  date: _expirationInsurance,
                  onSave: (date) =>
                      setState(() => _expirationInsurance = date)),
              getStyledDateAsText(
                  context, currentCar.getCurrentInsurance()?.expirationDate)),
          Divider(),
        ],
      ),
    );
  }

  Widget _buildPriceEditRow() {
    // return _buildFormField(carCons[0]);
    return Flexible(
      flex: 1,
      child: Row(children: [
        Flexible(
          flex: 4,
          child: Padding(
            padding: const EdgeInsets.all(8),
            child: AddEditTextField(
                controller: insuranceCons[2], hint: "Cena", onlyNumbers: true),
          ),
        ),
        Flexible(
          flex: 3,
          child: CurrencyPicker(
              onChanged: (value) => setState(() => _currency = value),
              initialValue: _currency),
        )
      ]),
    );
  }

  Widget _buildInfoRow(String first, String? second, Widget Function() editingF,
      [Text? child]) {
    Widget text = child ?? Text(second ?? "");
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Flexible(
          flex: 2,
          child: Text(
            "$first: ",
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
        ),
        editing ? editingF() : text
      ],
    );
  }

  Widget _buildFormField(TextEditingController controller,
      [String? Function(String?)? validator]) {
    return Flexible(
        child: TextFormField(
      controller: controller,
      validator: validator,
    ));
  }

  Widget _buildBox(Widget child, Color color) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Container(
        decoration: BoxDecoration(
          color: color,
          border: Border.all(color: Colors.teal),
        ),
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: child,
        ),
      ),
    );
  }
}
