// form_widgets.dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:url_launcher/url_launcher_string.dart';

import 'package:on_field_work/helpers/widgets/image_viewer_dialog.dart';
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';

/// 🔹 Common Colors & Styles
final _hintStyle = TextStyle(fontSize: 14, color: Colors.grey[600]);
final _tileDecoration = BoxDecoration(
  color: Colors.grey.shade100,
  borderRadius: BorderRadius.circular(8),
  border: Border.all(color: Colors.grey.shade300),
);

/// ==========================
/// Section Title
/// ==========================
class SectionTitle extends StatelessWidget {
  final IconData icon;
  final String title;
  final bool requiredField;

  const SectionTitle({
    required this.icon,
    required this.title,
    this.requiredField = false,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final color = Colors.grey[700];
    return Row(
      children: [
        Icon(icon, color: color, size: 18),
        const SizedBox(width: 8),
        RichText(
          text: TextSpan(
            style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                  fontWeight: FontWeight.w600,
                  color: Colors.black87,
                ),
            children: [
              TextSpan(text: title),
              if (requiredField)
                const TextSpan(
                  text: ' *',
                  style: TextStyle(color: Colors.red),
                ),
            ],
          ),
        ),
      ],
    );
  }
}

/// ==========================
/// Custom Text Field
/// ==========================
class CustomTextField extends StatelessWidget {
  final TextEditingController controller;
  final String hint;
  final int maxLines;
  final TextInputType keyboardType;
  final String? Function(String?)? validator;
  final Widget? suffixIcon; 

  const CustomTextField({
    required this.controller,
    required this.hint,
    this.maxLines = 1,
    this.keyboardType = TextInputType.text,
    this.validator,
    this.suffixIcon, 
    Key? key,
  }) ;

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      controller: controller,
      maxLines: maxLines,
      keyboardType: keyboardType,
      validator: validator,
      decoration: InputDecoration(
        hintText: hint,
        hintStyle: _hintStyle,
        filled: true,
        fillColor: Colors.grey.shade100,
        contentPadding:
            const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
        suffixIcon: suffixIcon,
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(8),
          borderSide: BorderSide(color: Colors.grey.shade300),
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(8),
          borderSide: BorderSide(color: Colors.grey.shade300),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(8),
          borderSide: const BorderSide(color: Colors.blueAccent, width: 1.5),
        ),
      ),
    );
  }
}

/// ==========================
/// Dropdown Tile
/// ==========================
class DropdownTile extends StatelessWidget {
  final String title;
  final VoidCallback onTap;

  const DropdownTile({
    required this.title,
    required this.onTap,
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
        decoration: _tileDecoration,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Expanded(
              child: Text(title,
                  style: const TextStyle(fontSize: 14, color: Colors.black87),
                  overflow: TextOverflow.ellipsis),
            ),
            const Icon(Icons.arrow_drop_down),
          ],
        ),
      ),
    );
  }
}

/// ==========================
/// Tile Container
/// ==========================
class TileContainer extends StatelessWidget {
  final Widget child;

  const TileContainer({required this.child, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) => Container(
      padding: const EdgeInsets.all(14),
      decoration: _tileDecoration,
      child: child);
}

/// ==========================
/// Attachments Section (Reusable)
/// ==========================
class AttachmentsSection<T extends GetxController> extends StatelessWidget {
  final T controller; // 🔹 Now any controller can be passed
  final RxList<File> attachments;
  final RxList<Map<String, dynamic>> existingAttachments;
  final ValueChanged<File> onRemoveNew;
  final ValueChanged<Map<String, dynamic>>? onRemoveExisting;
  final VoidCallback onAdd;

  const AttachmentsSection({
    required this.controller,
    required this.attachments,
    required this.existingAttachments,
    required this.onRemoveNew,
    this.onRemoveExisting,
    required this.onAdd,
    Key? key,
  }) : super(key: key);

  static const allowedImageExtensions = ['jpg', 'jpeg', 'png'];

  bool _isImageFile(File file) {
    final ext = file.path.split('.').last.toLowerCase();
    return allowedImageExtensions.contains(ext);
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      final activeExisting =
          existingAttachments.where((doc) => doc['isActive'] != false).toList();

      final imageFiles = attachments.where(_isImageFile).toList();
      final imageExisting = activeExisting
          .where((d) =>
              (d['contentType']?.toString().startsWith('image/') ?? false))
          .toList();

      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          if (activeExisting.isNotEmpty) ...[
            const Text("Existing Attachments",
                style: TextStyle(fontWeight: FontWeight.w600)),
            const SizedBox(height: 8),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: activeExisting.map((doc) {
                final isImage =
                    doc['contentType']?.toString().startsWith('image/') ??
                        false;
                final url = doc['url'];
                final fileName = doc['fileName'] ?? 'Unnamed';

                return _buildExistingTile(
                  context,
                  doc,
                  isImage,
                  url,
                  fileName,
                  imageExisting,
                );
              }).toList(),
            ),
            const SizedBox(height: 16),
          ],
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              ...attachments.map((file) => GestureDetector(
                    onTap: () => _onNewTap(context, file, imageFiles),
                    child: _AttachmentTile(
                      file: file,
                      onRemove: () => onRemoveNew(file),
                    ),
                  )),
              _buildActionTile(Icons.attach_file, onAdd),
              _buildActionTile(Icons.camera_alt, () {
                // 🔹 Dynamically call pickFromCamera if it exists
                final fn = controller as dynamic;
                if (fn.pickFromCamera != null) {
                  fn.pickFromCamera();
                } else {
                  showAppSnackbar(
                    title: 'Error',
                    message:
                        'This controller does not support camera attachments.',
                    type: SnackbarType.error,
                  );
                }
              }),
            ],
          ),
        ],
      );
    });
  }

  /// helper for new file tap
  void _onNewTap(BuildContext context, File file, List<File> imageFiles) {
    if (_isImageFile(file)) {
      showDialog(
        context: context,
        builder: (_) => ImageViewerDialog(
          imageSources: imageFiles,
          initialIndex: imageFiles.indexOf(file),
        ),
      );
    } else {
      showAppSnackbar(
        title: 'Info',
        message: 'Preview for this file type is not supported.',
        type: SnackbarType.info,
      );
    }
  }

  /// helper for existing file tile
  Widget _buildExistingTile(
    BuildContext context,
    Map<String, dynamic> doc,
    bool isImage,
    String? url,
    String fileName,
    List<Map<String, dynamic>> imageExisting,
  ) {
    return Stack(
      clipBehavior: Clip.none,
      children: [
        GestureDetector(
          onTap: () async {
            if (isImage) {
              final sources = imageExisting.map((e) => e['url']).toList();
              final idx = imageExisting.indexOf(doc);
              showDialog(
                context: context,
                builder: (_) =>
                    ImageViewerDialog(imageSources: sources, initialIndex: idx),
              );
            } else if (url != null && await canLaunchUrlString(url)) {
              await launchUrlString(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: _tileDecoration.copyWith(
              border: Border.all(color: Colors.grey.shade300),
              borderRadius: BorderRadius.circular(6),
            ),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(isImage ? Icons.image : Icons.insert_drive_file,
                    size: 20, color: Colors.grey[600]),
                const SizedBox(width: 7),
                ConstrainedBox(
                  constraints: const BoxConstraints(maxWidth: 120),
                  child: Text(fileName,
                      overflow: TextOverflow.ellipsis,
                      style: const TextStyle(fontSize: 12)),
                ),
              ],
            ),
          ),
        ),
        if (onRemoveExisting != null)
          Positioned(
            top: -6,
            right: -6,
            child: IconButton(
              icon: const Icon(Icons.close, color: Colors.red, size: 18),
              onPressed: () => onRemoveExisting?.call(doc),
            ),
          ),
      ],
    );
  }

  Widget _buildActionTile(IconData icon, VoidCallback onTap) => GestureDetector(
        onTap: onTap,
        child: Container(
          width: 50,
          height: 50,
          decoration: _tileDecoration.copyWith(
            border: Border.all(color: Colors.grey.shade400),
          ),
          child: Icon(icon, size: 30, color: Colors.grey),
        ),
      );
}

/// ==========================
/// Attachment Tile
/// ==========================
class _AttachmentTile extends StatelessWidget {
  final File file;
  final VoidCallback onRemove;

  const _AttachmentTile({required this.file, required this.onRemove});

  @override
  Widget build(BuildContext context) {
    final fileName = file.path.split('/').last;
    final extension = fileName.split('.').last.toLowerCase();
    final isImage =
        AttachmentsSection.allowedImageExtensions.contains(extension);

    final (icon, color) = _fileIcon(extension);

    return Stack(
      clipBehavior: Clip.none,
      children: [
        Container(
          width: 80,
          height: 80,
          decoration: _tileDecoration,
          child: isImage
              ? ClipRRect(
                  borderRadius: BorderRadius.circular(8),
                  child: Image.file(file, fit: BoxFit.cover),
                )
              : Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Icon(icon, color: color, size: 30),
                    const SizedBox(height: 4),
                    Text(extension.toUpperCase(),
                        style: TextStyle(
                            fontSize: 10,
                            fontWeight: FontWeight.bold,
                            color: color)),
                  ],
                ),
        ),
        Positioned(
          top: -6,
          right: -6,
          child: IconButton(
            icon: const Icon(Icons.close, color: Colors.red, size: 18),
            onPressed: onRemove,
          ),
        ),
      ],
    );
  }

  static (IconData, Color) _fileIcon(String ext) {
    switch (ext) {
      case 'pdf':
        return (Icons.picture_as_pdf, Colors.redAccent);
      case 'doc':
      case 'docx':
        return (Icons.description, Colors.blueAccent);
      case 'xls':
      case 'xlsx':
        return (Icons.table_chart, Colors.green);
      case 'txt':
        return (Icons.article, Colors.grey);
      default:
        return (Icons.insert_drive_file, Colors.blueGrey);
    }
  }
}
