import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:kmobile/api/services/cheque_service.dart';
import 'package:kmobile/data/models/user.dart';
import 'package:kmobile/di/injection.dart';
import 'package:kmobile/features/fund_transfer/screens/transaction_pin_screen.dart';
import 'package:kmobile/l10n/app_localizations.dart';

class StopMultipleChequesScreen extends StatefulWidget {
  final User selectedAccount;
  final String date;
  final String instrType;
  final String fromCheque;
  final String toCheque;

  const StopMultipleChequesScreen(
      {super.key,
      required this.selectedAccount,
      required this.date,
      required this.instrType,
      required this.fromCheque,
      required this.toCheque});

  @override
  State<StopMultipleChequesScreen> createState() =>
      _StopMultipleChequesScreenState();
}

class _StopMultipleChequesScreenState extends State<StopMultipleChequesScreen> {
  final _formKey = GlobalKey<FormState>();
  final _stopFromChequeNoController = TextEditingController();
  final _stopToChequeNoController = TextEditingController();
  final _stopIssueDateController = TextEditingController();
  final _stopExpiryDateController = TextEditingController();
  final _stopAmountController = TextEditingController();
  final _chequeService = getIt<ChequeService>();

  String? _selectedComment;
  final _otherCommentController = TextEditingController();
  bool _showOtherCommentField = false;
  final List<String> _commentOptions = [
    'Cheque Lost',
    'Cheque Stolen',
    'Cheque Missing',
    'Cheque Damaged',
    'Other'
  ];

  String _formatDate(String dateString) {
    if (dateString.length != 8) {
      return dateString; // Return as is if not in expected ddmmyyyy format
    }
    try {
      final day = dateString.substring(0, 2);
      final month = dateString.substring(2, 4);
      final year = dateString.substring(4, 8);
      return '$day/$month/$year';
    } catch (e) {
      return dateString; // Return original string on error
    }
  }

  Future<void> _selectDate(TextEditingController controller) async {
    final DateTime? picked = await showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime.now(),
      lastDate: DateTime(2101),
    );
    if (picked != null) {
      setState(() {
        controller.text =
            '${picked.day.toString().padLeft(2, '0')}/${picked.month.toString().padLeft(2, '0')}/${picked.year}';
      });
    }
  }

  Future<void> _showResponseDialog(String title, String message) async {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text(title),
          content: SingleChildScrollView(
            child: ListBody(
              children: <Widget>[
                Text(message),
              ],
            ),
          ),
          actions: <Widget>[
            TextButton(
              child: const Text('Close'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context).stopMultipleChequesTitle),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: ListView(
            children: [
              Card(
                elevation: 0,
                margin: const EdgeInsets.symmetric(vertical: 8.0),
                child: ListTile(
                  leading: Image.asset(
                    'assets/images/logo.png',
                    width: 40,
                    height: 40,
                  ),
                  title: Text(widget.selectedAccount.accountNo!),
                  subtitle:
                      Text(AppLocalizations.of(context).accountNumberTitle),
                ),
              ),
              const SizedBox(height: 24),
              TextFormField(
                controller: _stopFromChequeNoController,
                decoration: InputDecoration(
                  labelText: AppLocalizations.of(context).fromChequeNumberHint,
                  border: const OutlineInputBorder(),
                  errorMaxLines: 2,
                ),
                keyboardType: TextInputType.number,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return AppLocalizations.of(context)
                        .pleaseEnterChequeNumberError;
                  }
                  final chequeNumber = int.tryParse(value);
                  final fromCheque = int.tryParse(widget.fromCheque);
                  final toCheque = int.tryParse(widget.toCheque);
                  if (chequeNumber == null ||
                      fromCheque == null ||
                      toCheque == null) {
                    return AppLocalizations.of(context)
                        .invalidChequeNumberFormatError;
                  }
                  if (chequeNumber < fromCheque || chequeNumber > toCheque) {
                    return AppLocalizations.of(context).chequeNumberRangeError(
                        widget.fromCheque, widget.toCheque);
                  }
                  return null;
                },
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: _stopToChequeNoController,
                decoration: InputDecoration(
                  labelText: AppLocalizations.of(context).toChequeNumberHint,
                  border: const OutlineInputBorder(),
                  errorMaxLines: 2,
                ),
                keyboardType: TextInputType.number,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return AppLocalizations.of(context)
                        .pleaseEnterChequeNumberError;
                  }
                  final chequeNumber = int.tryParse(value);
                  final fromCheque = int.tryParse(widget.fromCheque);
                  final toCheque = int.tryParse(widget.toCheque);
                  if (chequeNumber == null ||
                      fromCheque == null ||
                      toCheque == null) {
                    return AppLocalizations.of(context)
                        .invalidChequeNumberFormatError;
                  }
                  if (chequeNumber < fromCheque || chequeNumber > toCheque) {
                    return AppLocalizations.of(context).chequeNumberRangeError(
                        widget.fromCheque, widget.toCheque);
                  }
                  return null;
                },
              ),
              const SizedBox(height: 16),
              TextFormField(
                initialValue: widget.instrType,
                readOnly: true,
                decoration: InputDecoration(
                  labelText: AppLocalizations.of(context).instrumentTypeLabel,
                  border: const OutlineInputBorder(),
                ),
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: _stopIssueDateController,
                readOnly: true,
                onTap: () => _selectDate(_stopIssueDateController),
                decoration: InputDecoration(
                  labelText: AppLocalizations.of(context).stopIssueDateHint,
                  border: const OutlineInputBorder(),
                  suffixIcon: IconButton(
                    icon: const Icon(Icons.calendar_today),
                    onPressed: () => _selectDate(_stopIssueDateController),
                  ),
                ),
                keyboardType: TextInputType.datetime,
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: _stopExpiryDateController,
                readOnly: true,
                onTap: () => _selectDate(_stopExpiryDateController),
                decoration: InputDecoration(
                  labelText: AppLocalizations.of(context).stopExpiryDateHint,
                  border: const OutlineInputBorder(),
                  suffixIcon: IconButton(
                    icon: const Icon(Icons.calendar_today),
                    onPressed: () => _selectDate(_stopExpiryDateController),
                  ),
                ),
                keyboardType: TextInputType.datetime,
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: _stopAmountController,
                decoration: InputDecoration(
                  labelText: AppLocalizations.of(context).stopAmountHint,
                  border: const OutlineInputBorder(),
                ),
                keyboardType: TextInputType.number,
              ),
              const SizedBox(height: 16),
              DropdownButtonFormField<String>(
                value: _selectedComment,
                items: _commentOptions.map((String value) {
                  return DropdownMenuItem<String>(
                    value: value,
                    child: Text(value),
                  );
                }).toList(),
                onChanged: (newValue) {
                  setState(() {
                    _selectedComment = newValue;
                    _showOtherCommentField = newValue == 'Other';
                  });
                },
                decoration: InputDecoration(
                  labelText: AppLocalizations.of(context).stopCommentHint,
                  border: const OutlineInputBorder(),
                ),
              ),
              if (_showOtherCommentField)
                Padding(
                  padding: const EdgeInsets.only(top: 16.0),
                  child: TextFormField(
                    controller: _otherCommentController,
                    decoration: const InputDecoration(
                      labelText: "Other Reasons :",
                      border: OutlineInputBorder(),
                    ),
                    validator: (value) {
                      return null;
                    },
                  ),
                ),
              const SizedBox(height: 16),
              TextFormField(
                initialValue: _formatDate(widget.date),
                readOnly: true,
                decoration: InputDecoration(
                  labelText:
                      AppLocalizations.of(context).chequebookIssueDateHint,
                  border: const OutlineInputBorder(),
                ),
              ),
              const SizedBox(height: 32),
              ElevatedButton(
                onPressed: () {
                  if (_formKey.currentState!.validate()) {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => TransactionPinScreen(
                          onPinCompleted: (ctx, pin) async {
                            Navigator.pop(context);
                            try {
                              final response = await _chequeService.stopCheque(
                                accountno: widget.selectedAccount.accountNo!,
                                stopFromChequeNo:
                                    _stopFromChequeNoController.text,
                                instrType: widget.instrType,
                                stopToChequeNo: _stopToChequeNoController.text,
                                stopIssueDate: _stopIssueDateController.text,
                                stopExpiryDate: _stopExpiryDateController.text,
                                stopAmount: _stopAmountController.text,
                                stopComment: _selectedComment == 'Other'
                                    ? _otherCommentController.text
                                    : _selectedComment ?? '',
                                chequeIssueDate: widget.date,
                                tpin: pin,
                              );
                              if (!mounted) return;
                              final decodedResponse = jsonDecode(response);
                              String responseString = response.toString(); // used as the case only for incorrect TPIN
                              final status = decodedResponse['status'];
                              final message = decodedResponse['message'];
                              final code = decodedResponse['code'];
                              if (status == 'SUCCESS') {
                                _showResponseDialog('Success', message);
                              } if (status == 'ERROR') {
                                String errMessage = "error";
                                if(code == '0429') {
                                  errMessage = 'The selected Cheque is already stopped';
                                } else if(code == '0748') {
                                  errMessage = 'The selected Cheque is already presented';
                                }
                                _showResponseDialog('Error', errMessage);
                              }
                              if(responseString.contains('INCORRECT_TPIN')){
                                _showResponseDialog('Invalid TPIN',
                                      'The TPIN you entered is incorrect. Please try again.');
                              }
                            } on Exception catch (e) {
                              try {
                                final errorBodyString =
                                    e.toString().split('Exception: ')[1];
                                final errorBody = jsonDecode(errorBodyString);
                                if (errorBody.containsKey('error') &&
                                    errorBody['error'] == 'INCORRECT_TPIN') {
                                  _showResponseDialog('Invalid TPIN',
                                      'The TPIN you entered is incorrect. Please try again.');
                                } else {
                                  _showResponseDialog(
                                      'Error', 'Internal Server Error');
                                }
                              } catch (_) {
                                _showResponseDialog(
                                    'Error', 'Internal Server Error');
                              }
                            }
                          },
                        ),
                      ),
                    );
                  }
                },
                child: Text(AppLocalizations.of(context).stopChequeButton),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
