import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:lunchpick/core/utils/app_logger.dart';
import 'package:lunchpick/presentation/pages/calendar/widgets/visit_confirmation_dialog.dart';
import 'package:lunchpick/presentation/providers/restaurant_provider.dart';

/// 알림 payload 데이터 모델
class NotificationPayload {
  final String type;
  final String restaurantId;
  final String restaurantName;
  final DateTime recommendationTime;

  NotificationPayload({
    required this.type,
    required this.restaurantId,
    required this.restaurantName,
    required this.recommendationTime,
  });

  factory NotificationPayload.fromString(String payload) {
    try {
      final parts = payload.split('|');
      if (parts.length < 4) {
        throw FormatException(
          'Invalid payload format - expected 4 parts but got ${parts.length}: $payload',
        );
      }

      // 각 필드 유효성 검증
      if (parts[0].isEmpty) {
        throw FormatException('Type cannot be empty');
      }
      if (parts[1].isEmpty) {
        throw FormatException('Restaurant ID cannot be empty');
      }
      if (parts[2].isEmpty) {
        throw FormatException('Restaurant name cannot be empty');
      }

      // DateTime 파싱 시도
      DateTime? recommendationTime;
      try {
        recommendationTime = DateTime.parse(parts[3]);
      } catch (e) {
        throw FormatException('Invalid date format: ${parts[3]}. Error: $e');
      }

      return NotificationPayload(
        type: parts[0],
        restaurantId: parts[1],
        restaurantName: parts[2],
        recommendationTime: recommendationTime,
      );
    } catch (e) {
      // 더 상세한 오류 정보 제공
      AppLogger.error('NotificationPayload parsing error', error: e);
      AppLogger.debug('Original payload: $payload');
      rethrow;
    }
  }

  String toString() {
    return '$type|$restaurantId|$restaurantName|${recommendationTime.toIso8601String()}';
  }
}

/// 알림 핸들러 StateNotifier
class NotificationHandlerNotifier extends StateNotifier<AsyncValue<void>> {
  final Ref _ref;

  NotificationHandlerNotifier(this._ref) : super(const AsyncValue.data(null));

  /// 알림 클릭 처리
  Future<void> handleNotificationTap(
    BuildContext context,
    String? payload,
  ) async {
    if (payload == null || payload.isEmpty) {
      AppLogger.debug('Notification payload is null or empty');
      return;
    }

    AppLogger.debug('Handling notification with payload: $payload');

    try {
      // 기존 형식 (visit_reminder:restaurantName) 처리
      if (payload.startsWith('visit_reminder:')) {
        final restaurantName = payload.substring(15);
        AppLogger.debug('Legacy format - Restaurant name: $restaurantName');

        // 맛집 이름으로 ID 찾기
        final restaurantsAsync = await _ref.read(restaurantListProvider.future);
        final restaurant = restaurantsAsync.firstWhere(
          (r) => r.name == restaurantName,
          orElse: () =>
              throw Exception('Restaurant not found: $restaurantName'),
        );

        // 방문 확인 다이얼로그 표시
        if (context.mounted) {
          await VisitConfirmationDialog.show(
            context: context,
            restaurantId: restaurant.id,
            restaurantName: restaurant.name,
            recommendationTime: DateTime.now().subtract(
              const Duration(hours: 2),
            ),
          );
        }
      } else {
        // 새로운 형식의 payload 처리
        AppLogger.debug('Attempting to parse new format payload');

        try {
          final notificationPayload = NotificationPayload.fromString(payload);
          AppLogger.debug(
            'Successfully parsed payload - Type: ${notificationPayload.type}, RestaurantId: ${notificationPayload.restaurantId}',
          );

          if (notificationPayload.type == 'visit_reminder') {
            // 방문 확인 다이얼로그 표시
            if (context.mounted) {
              final confirmed = await VisitConfirmationDialog.show(
                context: context,
                restaurantId: notificationPayload.restaurantId,
                restaurantName: notificationPayload.restaurantName,
                recommendationTime: notificationPayload.recommendationTime,
              );

              // 확인 또는 취소 후 캘린더 화면으로 이동
              if (context.mounted && confirmed != null) {
                context.go('/home?tab=calendar');
              }
            }
          }
        } catch (parseError) {
          AppLogger.debug(
            'Failed to parse new format, attempting fallback parsing',
          );
          AppLogger.debug('Parse error: $parseError');

          // Fallback: 간단한 파싱 시도
          if (payload.contains('|')) {
            final parts = payload.split('|');
            if (parts.isNotEmpty && parts[0] == 'visit_reminder') {
              // 최소한 캘린더로 이동
              if (context.mounted) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('알림을 처리했습니다. 방문 기록을 확인해주세요.')),
                );
                context.go('/home?tab=calendar');
              }
              return;
            }
          }

          // 파싱 실패 시 원래 에러 다시 발생
          rethrow;
        }
      }
    } catch (e, stackTrace) {
      AppLogger.error(
        'Error handling notification',
        error: e,
        stackTrace: stackTrace,
      );
      state = AsyncValue.error(e, stackTrace);

      // 에러 발생 시 기본적으로 캘린더 화면으로 이동
      if (context.mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('알림 처리 중 오류가 발생했습니다: ${e.toString()}'),
            backgroundColor: Colors.red,
          ),
        );
        context.go('/home?tab=calendar');
      }
    }
  }
}

/// NotificationHandler Provider
final notificationHandlerProvider =
    StateNotifierProvider<NotificationHandlerNotifier, AsyncValue<void>>((ref) {
      return NotificationHandlerNotifier(ref);
    });
