import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:marco/controller/expense/expense_detail_controller.dart';
import 'package:marco/controller/project_controller.dart';
import 'package:marco/controller/permission_controller.dart';

import 'package:marco/helpers/utils/date_time_utils.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/model/expense/expense_detail_model.dart';
import 'package:marco/helpers/widgets/image_viewer_dialog.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:marco/model/expense/reimbursement_bottom_sheet.dart';
import 'package:marco/helpers/widgets/my_snackbar.dart';
import 'package:marco/model/expense/comment_bottom_sheet.dart';

class ExpenseDetailScreen extends StatelessWidget {
  final String expenseId;
  const ExpenseDetailScreen({super.key, required this.expenseId});

  static Color getStatusColor(String? status, {String? colorCode}) {
    if (colorCode != null && colorCode.isNotEmpty) {
      try {
        return Color(int.parse(colorCode.replaceFirst('#', '0xff')));
      } catch (_) {}
    }
    switch (status) {
      case 'Approval Pending':
        return Colors.orange;
      case 'Process Pending':
        return Colors.blue;
      case 'Rejected':
        return Colors.red;
      case 'Paid':
        return Colors.green;
      default:
        return Colors.black;
    }
  }

  @override
  Widget build(BuildContext context) {
    final controller = Get.put(ExpenseDetailController());
    final projectController = Get.find<ProjectController>();
    controller.init(expenseId);
    final permissionController = Get.find<PermissionController>();

    return Scaffold(
      backgroundColor: const Color(0xFFF7F7F7),
      appBar: AppBar(
        automaticallyImplyLeading: false,
        elevation: 1,
        backgroundColor: Colors.white,
        title: Row(
          children: [
            IconButton(
              icon: const Icon(Icons.arrow_back_ios_new,
                  color: Colors.black, size: 20),
              onPressed: () => Get.offAllNamed('/dashboard/expense-main-page'),
            ),
            const SizedBox(width: 8),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  MyText.titleLarge('Expense Details',
                      fontWeight: 700, color: Colors.black),
                  MySpacing.height(2),
                  GetBuilder<ProjectController>(builder: (_) {
                    final projectName =
                        projectController.selectedProject?.name ??
                            'Select Project';
                    return Row(
                      children: [
                        const Icon(Icons.work_outline,
                            size: 14, color: Colors.grey),
                        MySpacing.width(4),
                        Expanded(
                          child: MyText.bodySmall(
                            projectName,
                            fontWeight: 600,
                            overflow: TextOverflow.ellipsis,
                            color: Colors.grey[700],
                          ),
                        ),
                      ],
                    );
                  }),
                ],
              ),
            ),
          ],
        ),
      ),
      body: SafeArea(
        child: Obx(() {
          if (controller.isLoading.value) {
            return _buildLoadingSkeleton();
          }

          final expense = controller.expense.value;

          if (controller.errorMessage.isNotEmpty || expense == null) {
            return Center(
              child: MyText.bodyMedium("No data to display."),
            );
          }

          final statusColor = getStatusColor(expense.status.name,
              colorCode: expense.status.color);
          final formattedAmount = NumberFormat.currency(
            locale: 'en_IN',
            symbol: '₹ ',
            decimalDigits: 2,
          ).format(expense.amount);

          // === CHANGE: Add proper bottom padding to always keep content away from device nav bar ===
          return SingleChildScrollView(
            padding: EdgeInsets.fromLTRB(
              8,
              8,
              8,
              16 + MediaQuery.of(context).padding.bottom, // KEY LINE
            ),
            child: Center(
              child: Container(
                constraints: const BoxConstraints(maxWidth: 520),
                child: Card(
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10)),
                  elevation: 3,
                  child: Padding(
                    padding: const EdgeInsets.symmetric(
                        vertical: 14, horizontal: 14),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        _InvoiceHeader(expense: expense),
                        Divider(height: 30, thickness: 1.2),
                        _InvoiceParties(expense: expense),
                        Divider(height: 30, thickness: 1.2),
                        _InvoiceDetailsTable(expense: expense),
                        Divider(height: 30, thickness: 1.2),
                        _InvoiceDocuments(documents: expense.documents),
                        Divider(height: 30, thickness: 1.2),
                        _InvoiceTotals(
                          expense: expense,
                          formattedAmount: formattedAmount,
                          statusColor: statusColor,
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          );
        }),
      ),
      bottomNavigationBar: Obx(() {
        final expense = controller.expense.value;
        if (expense == null || expense.nextStatus.isEmpty) {
          return const SizedBox();
        }
        return SafeArea(
          child: Container(
            decoration: const BoxDecoration(
              color: Colors.white,
              border: Border(top: BorderSide(color: Color(0x11000000))),
            ),
            padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
            child: Wrap(
              alignment: WrapAlignment.center,
              spacing: 10,
              runSpacing: 10,
              children: expense.nextStatus.where((next) {
                return permissionController.hasAnyPermission(
                  controller.parsePermissionIds(next.permissionIds),
                );
              }).map((next) {
                Color buttonColor = Colors.red;
                if (next.color.isNotEmpty) {
                  try {
                    buttonColor =
                        Color(int.parse(next.color.replaceFirst('#', '0xff')));
                  } catch (_) {}
                }
                return ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    minimumSize: const Size(100, 40),
                    padding:
                        const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
                    backgroundColor: buttonColor,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(6)),
                  ),
                  onPressed: () async {
                    const reimbursementId =
                        'f18c5cfd-7815-4341-8da2-2c2d65778e27';

                    if (expense.status.id == reimbursementId) {
                      // Open reimbursement flow
                      showModalBottomSheet(
                        context: context,
                        isScrollControlled: true,
                        shape: const RoundedRectangleBorder(
                          borderRadius:
                              BorderRadius.vertical(top: Radius.circular(16)),
                        ),
                        builder: (context) => ReimbursementBottomSheet(
                          expenseId: expense.id,
                          statusId: next.id,
                          onClose: () {},
                          onSubmit: ({
                            required String comment,
                            required String reimburseTransactionId,
                            required String reimburseDate,
                            required String reimburseById,
                            required String statusId,
                          }) async {
                            final success = await controller
                                .updateExpenseStatusWithReimbursement(
                              comment: comment,
                              reimburseTransactionId: reimburseTransactionId,
                              reimburseDate: reimburseDate,
                              reimburseById: reimburseById,
                              statusId: statusId,
                            );

                            if (success) {
                              showAppSnackbar(
                                title: 'Success',
                                message: 'Expense reimbursed successfully.',
                                type: SnackbarType.success,
                              );
                              await controller.fetchExpenseDetails();
                              return true;
                            } else {
                              showAppSnackbar(
                                title: 'Error',
                                message: 'Failed to reimburse expense.',
                                type: SnackbarType.error,
                              );
                              return false;
                            }
                          },
                        ),
                      );
                    } else {
                      // ✨ New: Show comment sheet
                      final comment =
                          await showCommentBottomSheet(context, next.name);
                      if (comment == null) return;

                      final success = await controller.updateExpenseStatus(
                        next.id,
                        comment: comment,
                      );

                      if (success) {
                        showAppSnackbar(
                          title: 'Success',
                          message:
                              'Expense moved to ${next.displayName.isNotEmpty ? next.displayName : next.name}',
                          type: SnackbarType.success,
                        );
                        await controller.fetchExpenseDetails();
                      } else {
                        showAppSnackbar(
                          title: 'Error',
                          message: 'Failed to update status.',
                          type: SnackbarType.error,
                        );
                      }
                    }
                  },
                  child: MyText.labelMedium(
                    next.displayName.isNotEmpty ? next.displayName : next.name,
                    color: Colors.white,
                    fontWeight: 600,
                    overflow: TextOverflow.ellipsis,
                  ),
                );
              }).toList(),
            ),
          ),
        );
      }),
    );
  }

  Widget _buildLoadingSkeleton() {
    return ListView(
      padding: const EdgeInsets.all(16),
      children: List.generate(5, (index) {
        return Container(
          margin: const EdgeInsets.only(bottom: 16),
          height: 80,
          decoration: BoxDecoration(
            color: Colors.grey[300],
            borderRadius: BorderRadius.circular(10),
          ),
        );
      }),
    );
  }
}

// ---------------- INVOICE SUB-COMPONENTS ----------------

class _InvoiceHeader extends StatelessWidget {
  final ExpenseDetailModel expense;
  const _InvoiceHeader({required this.expense});

  @override
  Widget build(BuildContext context) {
    final dateString = DateTimeUtils.convertUtcToLocal(
        expense.transactionDate.toString(),
        format: 'dd-MM-yyyy');

    final statusColor = ExpenseDetailScreen.getStatusColor(expense.status.name,
        colorCode: expense.status.color);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Row(
              children: [
                const Icon(Icons.calendar_month, size: 18, color: Colors.grey),
                MySpacing.width(6),
                MyText.bodySmall('Date:', fontWeight: 600),
                MySpacing.width(6),
                MyText.bodySmall(dateString, fontWeight: 600),
              ],
            ),
            Container(
              decoration: BoxDecoration(
                color: statusColor.withOpacity(0.15),
                borderRadius: BorderRadius.circular(8),
              ),
              padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
              child: Row(
                children: [
                  Icon(Icons.flag, size: 16, color: statusColor),
                  MySpacing.width(4),
                  MyText.labelSmall(
                    expense.status.name,
                    color: statusColor,
                    fontWeight: 600,
                  ),
                ],
              ),
            ),
          ],
        )
      ],
    );
  }
}

class _InvoiceParties extends StatelessWidget {
  final ExpenseDetailModel expense;
  const _InvoiceParties({required this.expense});

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _labelValueBlock('Project', expense.project.name),
        MySpacing.height(16),
        _labelValueBlock(
          'Paid By:',
          '${expense.paidBy.firstName} ${expense.paidBy.lastName}',
        ),
        MySpacing.height(16),
        _labelValueBlock('Supplier', expense.supplerName),
        MySpacing.height(16),
        _labelValueBlock(
          'Created By:',
          '${expense.createdBy.firstName} ${expense.createdBy.lastName}',
        ),
      ],
    );
  }

  Widget _labelValueBlock(String label, String value) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        MyText.bodySmall(
          label,
          fontWeight: 600,
        ),
        MySpacing.height(4),
        MyText.bodySmall(
          value,
          fontWeight: 500,
          softWrap: true,
          maxLines: null, // Allow full wrapping
        ),
      ],
    );
  }
}

class _InvoiceDetailsTable extends StatelessWidget {
  final ExpenseDetailModel expense;
  const _InvoiceDetailsTable({required this.expense});

  @override
  Widget build(BuildContext context) {
    final transactionDate = DateTimeUtils.convertUtcToLocal(
        expense.transactionDate.toString(),
        format: 'dd-MM-yyyy hh:mm a');
    final createdAt = DateTimeUtils.convertUtcToLocal(
        expense.createdAt.toString(),
        format: 'dd-MM-yyyy hh:mm a');

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _detailItem("Expense Type:", expense.expensesType.name),
        _detailItem("Payment Mode:", expense.paymentMode.name),
        _detailItem("Transaction Date:", transactionDate),
        _detailItem("Created At:", createdAt),
        _detailItem("Pre-Approved:", expense.preApproved ? 'Yes' : 'No'),
        _detailItem("Description:",
            expense.description.trim().isNotEmpty ? expense.description : '-',
            isDescription: true),
      ],
    );
  }

  Widget _detailItem(String title, String value, {bool isDescription = false}) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          MyText.bodySmall(
            title,
            fontWeight: 600,
          ),
          MySpacing.height(3),
          isDescription
              ? ExpandableDescription(description: value)
              : MyText.bodySmall(
                  value,
                  fontWeight: 500,
                ),
        ],
      ),
    );
  }
}

class _InvoiceDocuments extends StatelessWidget {
  final List<ExpenseDocument> documents;
  const _InvoiceDocuments({required this.documents});

  @override
  Widget build(BuildContext context) {
    if (documents.isEmpty) {
      return MyText.bodyMedium('No Supporting Documents', color: Colors.grey);
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        MyText.bodySmall("Supporting Documents:", fontWeight: 600),
        const SizedBox(height: 12),
        ListView.separated(
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          itemCount: documents.length,
          separatorBuilder: (_, __) => const SizedBox(height: 8),
          itemBuilder: (context, index) {
            final doc = documents[index];

            return GestureDetector(
              onTap: () async {
                final imageDocs = documents
                    .where((d) => d.contentType.startsWith('image/'))
                    .toList();

                final initialIndex =
                    imageDocs.indexWhere((d) => d.documentId == doc.documentId);

                if (imageDocs.isNotEmpty && initialIndex != -1) {
                  showDialog(
                    context: context,
                    builder: (_) => ImageViewerDialog(
                      imageSources:
                          imageDocs.map((e) => e.preSignedUrl).toList(),
                      initialIndex: initialIndex,
                    ),
                  );
                } else {
                  final Uri url = Uri.parse(doc.preSignedUrl);
                  if (await canLaunchUrl(url)) {
                    await launchUrl(url, mode: LaunchMode.externalApplication);
                  } else {
                    showAppSnackbar(
                      title: 'Error',
                      message: 'Could not open the document.',
                      type: SnackbarType.error,
                    );
                  }
                }
              },
              child: Container(
                padding:
                    const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey.shade300),
                  borderRadius: BorderRadius.circular(6),
                  color: Colors.grey.shade100,
                ),
                child: Row(
                  children: [
                    Icon(
                      doc.contentType.startsWith('image/')
                          ? Icons.image
                          : Icons.insert_drive_file,
                      size: 20,
                      color: Colors.grey[600],
                    ),
                    const SizedBox(width: 7),
                    Expanded(
                      child: MyText.labelSmall(
                        doc.fileName,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ],
    );
  }
}

class _InvoiceTotals extends StatelessWidget {
  final ExpenseDetailModel expense;
  final String formattedAmount;
  final Color statusColor;
  const _InvoiceTotals({
    required this.expense,
    required this.formattedAmount,
    required this.statusColor,
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        MyText.bodyLarge("Total:", fontWeight: 700),
        const Spacer(),
        MyText.bodyLarge(formattedAmount, fontWeight: 700),
      ],
    );
  }
}

class ExpandableDescription extends StatefulWidget {
  final String description;
  const ExpandableDescription({super.key, required this.description});

  @override
  State<ExpandableDescription> createState() => _ExpandableDescriptionState();
}

class _ExpandableDescriptionState extends State<ExpandableDescription> {
  bool isExpanded = false;

  @override
  Widget build(BuildContext context) {
    final isLong = widget.description.length > 100;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        MyText.bodySmall(
          widget.description,
          maxLines: isExpanded ? null : 2,
          overflow: isExpanded ? TextOverflow.visible : TextOverflow.ellipsis,
          fontWeight: 500,
        ),
        if (isLong || !isExpanded)
          InkWell(
            onTap: () => setState(() => isExpanded = !isExpanded),
            child: Padding(
              padding: const EdgeInsets.only(top: 4),
              child: MyText.labelSmall(
                isExpanded ? 'Show less' : 'Show more',
                fontWeight: 600,
                color: Colors.blue,
              ),
            ),
          ),
      ],
    );
  }
}
