import 'dart:io' show File, Platform;

import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:file_picker/file_picker.dart';
import 'package:go_router/go_router.dart';
import 'package:path_provider/path_provider.dart';
import 'package:qpay/screens/groups/controllers/group_controller.dart';
import 'package:qpay/screens/groups/models/create_group_from_file_response.dart';
import 'package:qpay/models/responsive_policy.dart';
import 'package:qpay/widgets/app_snack_bar.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';

class CreateGroupFromFileScreen extends StatefulWidget {
  const CreateGroupFromFileScreen({super.key});

  @override
  State<CreateGroupFromFileScreen> createState() =>
      _CreateGroupFromFileScreenState();
}

class _CreateGroupFromFileScreenState extends State<CreateGroupFromFileScreen> {
  late GroupController controller;
  final _formKey = GlobalKey<FormState>();
  final _groupNameController = TextEditingController();
  final _descriptionController = TextEditingController();
  String _currency = 'USD';
  List<int>? _fileBytes;
  String? _selectedFileName;

  @override
  void initState() {
    super.initState();
    controller = GroupController(context);
  }

  @override
  void dispose() {
    _groupNameController.dispose();
    _descriptionController.dispose();
    controller.dispose();
    super.dispose();
  }

  Future<void> _downloadTemplate() async {
    try {
      final bytes = await rootBundle.load('assets/group-batch-example.csv');
      final data = bytes.buffer.asUint8List();

      if (kIsWeb) {
        // Web: use url_launcher with a data URI
        final uri = Uri.dataFromString(
          String.fromCharCodes(data),
          mimeType: 'text/csv',
          encoding: null,
        );
        await launchUrl(uri, mode: LaunchMode.platformDefault);
      } else {
        // Mobile/desktop: write to temp file and open with url_launcher
        final dir = Platform.isAndroid
            ? await getTemporaryDirectory()
            : await getApplicationDocumentsDirectory();
        final file = File('${dir.path}/group-batch-example.csv');
        await file.writeAsBytes(data);
        final fileUri = Uri.file(file.path);
        if (await canLaunchUrl(fileUri)) {
          await launchUrl(fileUri, mode: LaunchMode.externalApplication);
        } else {
          throw Exception('Cannot open file');
        }
      }
    } catch (e) {
      if (mounted) {
        AppSnackBar.showError(context, 'Failed to download template: $e');
      }
    }
  }

  Future<void> _pickFile() async {
    final result = await FilePicker.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['csv'],
      withData: true,
    );

    if (result != null && result.files.isNotEmpty) {
      final file = result.files.first;
      if (file.bytes != null) {
        setState(() {
          _fileBytes = file.bytes;
          _selectedFileName = file.name;
        });
      }
    }
  }

  Future<void> _submit() async {
    if (!_formKey.currentState!.validate()) return;

    if (_fileBytes == null || _selectedFileName == null) {
      AppSnackBar.show(context, 'Please select a CSV file to upload.');
      return;
    }

    final prefs = await SharedPreferences.getInstance();
    final workspaceId = prefs.getString('workspaceId') ?? '';
    final userId = prefs.getString('userId') ?? '';

    final result = await controller.createGroupFromFile(
      groupName: _groupNameController.text.trim(),
      workspaceId: workspaceId,
      userId: userId,
      description: _descriptionController.text.trim().isEmpty
          ? null
          : _descriptionController.text.trim(),
      currency: _currency,
      fileBytes: _fileBytes!,
      fileName: _selectedFileName!,
    );

    if (!mounted) return;

    if (result.isSuccess) {
      final response = result.data!;
      if (response.isSuccess && response.batch != null) {
        final batch = response.batch!;
        final groupId = batch.recipientGroupId ?? '';

        AppSnackBar.showSuccess(
          context,
          'Group & batch created successfully. '
          '${response.successCount} of ${response.totalRows} rows processed.',
        );

        if (groupId.isNotEmpty && batch.id != null) {
          context.pushReplacement('/groups/batches/${batch.id}');
        }
      } else {
        // Partial failure — show errors
        _showErrorsBottomSheet(response);
      }
    } else {
      AppSnackBar.showError(
        context,
        result.error ?? 'Failed to create group from file.',
      );
    }
  }

  void _showErrorsBottomSheet(CreateGroupFromFileResponse response) {
    final isDark = Theme.of(context).brightness == Brightness.dark;

    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (sheetContext) {
        return Container(
          decoration: BoxDecoration(
            color: isDark ? const Color(0xFF1A1A2E) : Colors.white,
            borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
          ),
          padding: const EdgeInsets.fromLTRB(20, 12, 20, 24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Center(
                child: Container(
                  width: 40,
                  height: 4,
                  margin: const EdgeInsets.only(bottom: 16),
                  decoration: BoxDecoration(
                    color: Colors.grey.shade300,
                    borderRadius: BorderRadius.circular(2),
                  ),
                ),
              ),
              Row(
                children: [
                  Icon(
                    Icons.warning_amber_rounded,
                    color: Colors.orange.shade700,
                    size: 24,
                  ),
                  const SizedBox(width: 10),
                  Text(
                    'Upload completed with errors',
                    style: TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.w700,
                      color: isDark ? Colors.white : Colors.black87,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 8),
              Text(
                '${response.errorCount} of ${response.totalRows} rows failed. '
                '${response.successCount} rows succeeded.',
                style: TextStyle(fontSize: 13, color: Colors.grey.shade600),
              ),
              const SizedBox(height: 16),
              if (response.errors.isNotEmpty) ...[
                Flexible(
                  child: ConstrainedBox(
                    constraints: BoxConstraints(
                      maxHeight: MediaQuery.of(sheetContext).size.height * 0.4,
                    ),
                    child: ListView.separated(
                      shrinkWrap: true,
                      itemCount: response.errors.length,
                      separatorBuilder: (_, __) => const Divider(height: 1),
                      itemBuilder: (_, index) {
                        final error = response.errors[index];
                        return ListTile(
                          dense: true,
                          contentPadding: EdgeInsets.zero,
                          leading: CircleAvatar(
                            radius: 14,
                            backgroundColor: Colors.red.shade50,
                            child: Text(
                              '${error.lineNumber}',
                              style: TextStyle(
                                fontSize: 11,
                                fontWeight: FontWeight.w700,
                                color: Colors.red.shade700,
                              ),
                            ),
                          ),
                          title: Text(
                            error.name.isNotEmpty
                                ? '${error.name} (${error.account})'
                                : error.account,
                            style: const TextStyle(
                              fontSize: 13,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                          subtitle: Text(
                            error.message,
                            style: TextStyle(
                              fontSize: 12,
                              color: Colors.grey.shade600,
                            ),
                          ),
                        );
                      },
                    ),
                  ),
                ),
                const SizedBox(height: 16),
              ],
              SizedBox(
                width: double.infinity,
                child: ElevatedButton(
                  onPressed: () => Navigator.of(sheetContext).pop(),
                  style: ElevatedButton.styleFrom(
                    padding: const EdgeInsets.symmetric(vertical: 14),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(14),
                    ),
                  ),
                  child: const Text('Dismiss'),
                ),
              ),
            ],
          ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Create from File'), centerTitle: true),
      body: ListenableBuilder(
        listenable: controller,
        builder: (context, _) {
          return Center(
            child: LayoutBuilder(
              builder: (context, constraints) {
                final width = constraints.maxWidth > ResponsivePolicy.md
                    ? ResponsivePolicy.md.toDouble()
                    : constraints.maxWidth;
                return SizedBox(
                  width: width,
                  child: SingleChildScrollView(
                    padding: const EdgeInsets.all(20),
                    child: Form(
                      key: _formKey,
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          TextFormField(
                            controller: _groupNameController,
                            textInputAction: TextInputAction.next,
                            decoration: InputDecoration(
                              labelText: 'Group Name',
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                            ),
                            validator: (v) => (v == null || v.trim().isEmpty)
                                ? 'Group name is required'
                                : null,
                          ),
                          const SizedBox(height: 16),
                          TextFormField(
                            controller: _descriptionController,
                            textInputAction: TextInputAction.next,
                            decoration: InputDecoration(
                              labelText: 'Description (optional)',
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                            ),
                          ),
                          const SizedBox(height: 16),
                          DropdownButtonFormField<String>(
                            initialValue: _currency,
                            decoration: InputDecoration(
                              labelText: 'Currency',
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                            ),
                            items: const [
                              DropdownMenuItem(
                                value: 'USD',
                                child: Text('USD'),
                              ),
                              DropdownMenuItem(
                                value: 'ZWG',
                                child: Text('ZWG'),
                              ),
                            ],
                            onChanged: (v) {
                              if (v != null) setState(() => _currency = v);
                            },
                          ),
                          const SizedBox(height: 24),
                          Text(
                            'Recipients File',
                            style: TextStyle(
                              fontSize: 16,
                              fontWeight: FontWeight.w600,
                              color: Colors.grey.shade800,
                            ),
                          ),
                          const SizedBox(height: 4),
                          Text(
                            'Upload a CSV file with columns: name, account, amount, billProductName',
                            style: TextStyle(
                              fontSize: 13,
                              color: Colors.grey.shade600,
                            ),
                          ),
                          const SizedBox(height: 12),
                          InkWell(
                            onTap: _pickFile,
                            borderRadius: BorderRadius.circular(12),
                            child: Container(
                              padding: const EdgeInsets.all(20),
                              decoration: BoxDecoration(
                                border: Border.all(
                                  color: _fileBytes != null
                                      ? Theme.of(context).colorScheme.primary
                                      : Colors.grey.shade300,
                                  width: 1.5,
                                  style: BorderStyle.solid,
                                ),
                                borderRadius: BorderRadius.circular(12),
                                color: _fileBytes != null
                                    ? Theme.of(
                                        context,
                                      ).colorScheme.primary.withAlpha(12)
                                    : Colors.grey.shade50,
                              ),
                              child: Column(
                                children: [
                                  Icon(
                                    _fileBytes != null
                                        ? Icons.insert_drive_file
                                        : Icons.cloud_upload_outlined,
                                    size: 40,
                                    color: _fileBytes != null
                                        ? Theme.of(context).colorScheme.primary
                                        : Colors.grey.shade400,
                                  ),
                                  const SizedBox(height: 8),
                                  Text(
                                    _selectedFileName ??
                                        'Tap to select CSV file',
                                    style: TextStyle(
                                      fontSize: 14,
                                      fontWeight: FontWeight.w500,
                                      color: _fileBytes != null
                                          ? Theme.of(
                                              context,
                                            ).colorScheme.primary
                                          : Colors.grey.shade600,
                                    ),
                                    textAlign: TextAlign.center,
                                  ),
                                  if (_fileBytes == null) ...[
                                    const SizedBox(height: 4),
                                    Text(
                                      'Accepted format: .csv',
                                      style: TextStyle(
                                        fontSize: 12,
                                        color: Colors.grey.shade500,
                                      ),
                                    ),
                                  ],
                                ],
                              ),
                            ),
                          ),
                          const SizedBox(height: 8),
                          Align(
                            alignment: Alignment.centerLeft,
                            child: TextButton.icon(
                              onPressed: _downloadTemplate,
                              icon: const Icon(
                                Icons.download_rounded,
                                size: 18,
                              ),
                              label: const Text('Download Template'),
                              style: TextButton.styleFrom(
                                padding: const EdgeInsets.symmetric(
                                  horizontal: 12,
                                  vertical: 4,
                                ),
                                visualDensity: VisualDensity.compact,
                              ),
                            ),
                          ),
                          const SizedBox(height: 32),
                          ElevatedButton(
                            onPressed: controller.model.isLoading
                                ? null
                                : _submit,
                            style: ElevatedButton.styleFrom(
                              padding: const EdgeInsets.symmetric(vertical: 16),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                            ),
                            child: controller.model.isLoading
                                ? const SizedBox(
                                    height: 20,
                                    width: 20,
                                    child: CircularProgressIndicator(
                                      strokeWidth: 2,
                                      color: Colors.white,
                                    ),
                                  )
                                : const Text(
                                    'Upload & Create',
                                    style: TextStyle(fontSize: 16),
                                  ),
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              },
            ),
          );
        },
      ),
    );
  }
}
