import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

import '../../../../models/air_installation_data.dart';
import '../../../../models/air_collection_data.dart';
import '../../../../services/local_storage_service.dart';
import '../../../../services/api_service.dart';

class SubmissionLogEntry {
  final String type;
  final String title;
  final String stationCode;
  final DateTime submissionDateTime;
  final String? reportId;
  final String status;
  final String message;
  final Map<String, dynamic> rawData;
  bool isResubmitting;

  SubmissionLogEntry({
    required this.type,
    required this.title,
    required this.stationCode,
    required this.submissionDateTime,
    this.reportId,
    required this.status,
    required this.message,
    required this.rawData,
    this.isResubmitting = false,
  });
}

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

  @override
  State<AirManualDataStatusLog> createState() => _AirManualDataStatusLogState();
}

class _AirManualDataStatusLogState extends State<AirManualDataStatusLog> {
  final LocalStorageService _localStorageService = LocalStorageService();
  final ApiService _apiService = ApiService();

  List<SubmissionLogEntry> _installationLogs = [];
  List<SubmissionLogEntry> _collectionLogs = [];
  List<SubmissionLogEntry> _filteredInstallationLogs = [];
  List<SubmissionLogEntry> _filteredCollectionLogs = [];

  final Map<String, TextEditingController> _searchControllers = {};
  bool _isLoading = true;
  final Map<String, bool> _isResubmitting = {};

  @override
  void initState() {
    super.initState();
    _searchControllers['Installation'] = TextEditingController()..addListener(_filterLogs);
    _searchControllers['Collection'] = TextEditingController()..addListener(_filterLogs);
    _loadAllLogs();
  }

  @override
  void dispose() {
    _searchControllers['Installation']?.dispose();
    _searchControllers['Collection']?.dispose();
    super.dispose();
  }

  Future<void> _loadAllLogs() async {
    setState(() => _isLoading = true);
    final airLogs = await _localStorageService.getAllAirSamplingLogs();

    final List<SubmissionLogEntry> tempInstallation = [];
    final List<SubmissionLogEntry> tempCollection = [];

    for (var log in airLogs) {
      try {
        // Determine if this is an installation or collection
        final hasCollectionData = log['collectionData'] != null && (log['collectionData'] as Map).isNotEmpty;
        final isInstallation = !hasCollectionData && log['air_man_id'] != null;

        // Get station info from the correct location
        final stationInfo = isInstallation
            ? log['stationInfo'] ?? {}
            : log['collectionData']?['stationInfo'] ?? {};

        final stationName = stationInfo['station_name'] ?? 'Station ${log['stationID'] ?? 'Unknown'}';
        final stationCode = stationInfo['station_code'] ?? log['stationID'] ?? 'N/A';

        // Get correct timestamp
        final submissionDateTime = isInstallation
            ? _parseInstallationDateTime(log)
            : _parseCollectionDateTime(log['collectionData']);

        debugPrint('Processed ${isInstallation ? 'Installation' : 'Collection'} log:');
        debugPrint('  Station: $stationName ($stationCode)');
        debugPrint('  Original Date: ${submissionDateTime.toString()}');

        final entry = SubmissionLogEntry(
          type: isInstallation ? 'Installation' : 'Collection',
          title: stationName,
          stationCode: stationCode,
          submissionDateTime: submissionDateTime,
          reportId: isInstallation ? log['air_man_id']?.toString() : log['collectionData']?['air_man_id']?.toString(),
          status: log['status'] ?? 'L1',
          message: _getStatusMessage(log),
          rawData: log,
        );

        if (isInstallation) {
          tempInstallation.add(entry);
        } else {
          tempCollection.add(entry);
        }
      } catch (e) {
        debugPrint('Error processing log entry: $e');
      }
    }

    // Sort by datetime descending
    tempInstallation.sort((a, b) => b.submissionDateTime.compareTo(a.submissionDateTime));
    tempCollection.sort((a, b) => b.submissionDateTime.compareTo(a.submissionDateTime));

    if (mounted) {
      setState(() {
        _installationLogs = tempInstallation;
        _collectionLogs = tempCollection;
        _isLoading = false;
      });
      _filterLogs();
    }
  }

  DateTime _parseInstallationDateTime(Map<String, dynamic> log) {
    try {
      // First try to get the installation date and time
      if (log['installationDate'] != null) {
        final date = log['installationDate'];
        final time = log['installationTime'] ?? '00:00';
        return DateFormat('yyyy-MM-dd HH:mm').parse('$date $time');
      }

      // Fallback to sampling date if installation date not available
      if (log['samplingDate'] != null) {
        final date = log['samplingDate'];
        final time = log['samplingTime'] ?? '00:00';
        return DateFormat('yyyy-MM-dd HH:mm').parse('$date $time');
      }

      // If no dates found, check in the raw data structure
      if (log['data'] != null && log['data']['installationDate'] != null) {
        final date = log['data']['installationDate'];
        final time = log['data']['installationTime'] ?? '00:00';
        return DateFormat('yyyy-MM-dd HH:mm').parse('$date $time');
      }

      debugPrint('No valid installation date found in log: ${log.keys}');
      return DateTime.now();
    } catch (e) {
      debugPrint('Error parsing installation date: $e');
      return DateTime.now();
    }
  }

  DateTime _parseCollectionDateTime(Map<String, dynamic>? collectionData) {
    try {
      if (collectionData == null) {
        debugPrint('Collection data is null');
        return DateTime.now();
      }

      // First try the direct fields
      if (collectionData['collectionDate'] != null) {
        final date = collectionData['collectionDate'];
        final time = collectionData['collectionTime'] ?? '00:00';
        return DateFormat('yyyy-MM-dd HH:mm').parse('$date $time');
      }

      // Check for nested data structure
      if (collectionData['data'] != null && collectionData['data']['collectionDate'] != null) {
        final date = collectionData['data']['collectionDate'];
        final time = collectionData['data']['collectionTime'] ?? '00:00';
        return DateFormat('yyyy-MM-dd HH:mm').parse('$date $time');
      }

      debugPrint('No valid collection date found in data: ${collectionData.keys}');
      return DateTime.now();
    } catch (e) {
      debugPrint('Error parsing collection date: $e');
      return DateTime.now();
    }
  }

  String _getStatusMessage(Map<String, dynamic> log) {
    if (log['status'] == 'S2' || log['status'] == 'S3') {
      return 'Successfully submitted to server';
    } else if (log['status'] == 'L1' || log['status'] == 'L3') {
      return 'Saved locally (pending submission)';
    } else if (log['status'] == 'L4') {
      return 'Partial submission (images failed)';
    }
    return 'Submission status unknown';
  }

  void _filterLogs() {
    final installationQuery = _searchControllers['Installation']?.text.toLowerCase() ?? '';
    final collectionQuery = _searchControllers['Collection']?.text.toLowerCase() ?? '';

    setState(() {
      _filteredInstallationLogs = _installationLogs.where((log) => _logMatchesQuery(log, installationQuery)).toList();
      _filteredCollectionLogs = _collectionLogs.where((log) => _logMatchesQuery(log, collectionQuery)).toList();
    });
  }

  bool _logMatchesQuery(SubmissionLogEntry log, String query) {
    if (query.isEmpty) return true;
    return log.title.toLowerCase().contains(query) ||
        log.stationCode.toLowerCase().contains(query) ||
        (log.reportId?.toLowerCase() ?? '').contains(query);
  }

  Future<void> _resubmitData(SubmissionLogEntry log) async {
    final logKey = log.reportId ?? log.submissionDateTime.toIso8601String();
    if (mounted) {
      setState(() => _isResubmitting[logKey] = true);
    }

    try {
      final logData = log.rawData;
      final result = log.type == 'Installation'
          ? await _submitInstallation(logData)
          : await _submitCollection(logData);

      await _localStorageService.saveAirSamplingRecord(logData, logData['refID']);
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Resubmission successful!')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Resubmission failed: $e')),
        );
      }
    } finally {
      if (mounted) {
        setState(() => _isResubmitting.remove(logKey));
        await _loadAllLogs();
      }
    }
  }

  Future<Map<String, dynamic>> _submitInstallation(Map<String, dynamic> data) async {
    final dataToResubmit = AirInstallationData.fromJson(data);
    final result = await _apiService.post('air/manual/installation', dataToResubmit.toJsonForApi());

    final imageFiles = dataToResubmit.getImagesForUpload();
    if (imageFiles.isNotEmpty && result['success'] == true) {
      await _apiService.air.uploadInstallationImages(
        airManId: result['data']['air_man_id'].toString(),
        files: imageFiles,
      );
    }

    return result;
  }

  Future<Map<String, dynamic>> _submitCollection(Map<String, dynamic> data) async {
    final collectionData = data['collectionData'] ?? {};
    final dataToResubmit = AirCollectionData.fromMap(collectionData);
    final result = await _apiService.post('air/manual/collection', dataToResubmit.toJson());

    final imageFiles = dataToResubmit.getImagesForUpload();
    if (imageFiles.isNotEmpty && result['success'] == true) {
      await _apiService.air.uploadCollectionImages(
        airManId: dataToResubmit.airManId.toString(),
        files: imageFiles,
      );
    }

    return result;
  }

  @override
  Widget build(BuildContext context) {
    final hasAnyLogs = _installationLogs.isNotEmpty || _collectionLogs.isNotEmpty;
    final hasFilteredLogs = _filteredInstallationLogs.isNotEmpty || _filteredCollectionLogs.isNotEmpty;

    final logCategories = {
      'Installation': _filteredInstallationLogs,
      'Collection': _filteredCollectionLogs,
    };

    return Scaffold(
      appBar: AppBar(
        title: const Text('Air Sampling Status Log'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: _loadAllLogs,
            tooltip: 'Refresh logs',
          ),
        ],
      ),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : RefreshIndicator(
        onRefresh: _loadAllLogs,
        child: !hasAnyLogs
            ? const Center(child: Text('No air sampling logs found.'))
            : ListView(
          padding: const EdgeInsets.all(8.0),
          children: [
            ...logCategories.entries
                .where((entry) => entry.value.isNotEmpty)
                .map((entry) => _buildCategorySection(entry.key, entry.value)),
            if (!hasFilteredLogs && hasAnyLogs)
              const Center(
                child: Padding(
                  padding: EdgeInsets.all(24.0),
                  child: Text('No logs match your search.'),
                ),
              )
          ],
        ),
      ),
    );
  }

  Widget _buildCategorySection(String category, List<SubmissionLogEntry> logs) {
    final listHeight = (logs.length > 3 ? 3.5 : logs.length.toDouble()) * 75.0;

    return Card(
      margin: const EdgeInsets.symmetric(vertical: 8.0),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(category, style: Theme.of(context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold)),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              child: TextField(
                controller: _searchControllers[category],
                decoration: InputDecoration(
                  hintText: 'Search $category logs...',
                  prefixIcon: const Icon(Icons.search, size: 20),
                  isDense: true,
                  border: const OutlineInputBorder(),
                ),
              ),
            ),
            const Divider(),
            logs.isEmpty
                ? const Padding(
                padding: EdgeInsets.all(16.0),
                child: Center(child: Text('No logs match your search in this category.')))
                : ConstrainedBox(
              constraints: BoxConstraints(maxHeight: listHeight),
              child: ListView.builder(
                shrinkWrap: true,
                itemCount: logs.length,
                itemBuilder: (context, index) => _buildLogListItem(logs[index]),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildLogListItem(SubmissionLogEntry log) {
    final isSuccess = log.status == 'S2' || log.status == 'S3';
    final logKey = log.reportId ?? log.submissionDateTime.toIso8601String();
    final isResubmitting = _isResubmitting[logKey] ?? false;
    final title = log.title;
    final subtitle = DateFormat('yyyy-MM-dd HH:mm').format(log.submissionDateTime);

    return ExpansionTile(
      leading: Icon(
        isSuccess ? Icons.check_circle_outline : Icons.error_outline,
        color: isSuccess ? Colors.green : Colors.red,
      ),
      title: Text(title, style: const TextStyle(fontWeight: FontWeight.w500)),
      subtitle: Text(subtitle),
      trailing: !isSuccess
          ? (isResubmitting
          ? const SizedBox(
          height: 24,
          width: 24,
          child: CircularProgressIndicator(strokeWidth: 3))
          : IconButton(
        icon: const Icon(Icons.sync, color: Colors.blue),
        onPressed: () => _resubmitData(log),
      ))
          : null,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildDetailRow('Station Code:', log.stationCode),
              if (log.reportId != null) _buildDetailRow('Report ID:', log.reportId!),
              _buildDetailRow('Status:', log.message),
              _buildDetailRow('Type:', '${log.type} Sampling'),
              if (log.type == 'Collection')
                _buildDetailRow('Installation ID:', log.rawData['installationRefID']?.toString() ?? 'N/A'),
            ],
          ),
        )
      ],
    );
  }

  Widget _buildDetailRow(String label, String value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 2.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('$label ', style: const TextStyle(fontWeight: FontWeight.bold)),
          Expanded(child: Text(value)),
        ],
      ),
    );
  }
}