import 'dart:async';
import 'dart:math';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../core/error/exceptions.dart';
import '../../../../core/network/dio_client.dart';
import '../../../knowledge_base/data/datasources/kb_remote_datasource.dart';
import '../../data/datasources/chat_remote_datasource.dart';
import '../../data/repositories/chat_repository_impl.dart';
import 'chat_state.dart';

class ChatCubit extends Cubit<ChatState> {
  final ChatRepositoryImpl _repo;
  Timer? _rateLimitTimer;

  ChatCubit()
      : _repo = ChatRepositoryImpl(ChatRemoteDatasource(DioClient.instance)),
        super(ChatState(
          sessionId: 'sess_${Random().nextInt(999999)}',
          messages: [
            ChatMessage(
              id: 'welcome',
              text: '👋 Hello! I\'m your FinSim Investment Advisor. I can help you with:\n\n'
                  '• Real-time market data & prices\n'
                  '• Investment strategy questions\n'
                  '• Practice MCQ scenarios\n'
                  '• Financial concept explanations\n\n'
                  'What would you like to explore?',
              isUser: false,
              timestamp: DateTime.now(),
            ),
          ],
        ));

  Future<void> loadKnowledgeBases() async {
    try {
      final kbs = await KBRemoteDatasource(DioClient.instance).getKnowledgeBases();
      emit(state.copyWith(knowledgeBases: kbs));
    } catch (_) {}
  }

  void selectKB(String? kbId) {
    emit(state.copyWith(selectedKbId: () => kbId));
  }

  Future<void> sendMessage(String text) async {
    if (text.trim().isEmpty || state.isTyping || state.isRateLimited) return;

    final userMsg = ChatMessage(
      id: 'user_${DateTime.now().millisecondsSinceEpoch}',
      text: text.trim(),
      isUser: true,
      timestamp: DateTime.now(),
    );

    emit(state.copyWith(
      messages: [...state.messages, userMsg],
      isTyping: true,
    ));

    try {
      final response = await _repo.sendMessage(
        sessionId: state.sessionId,
        message: text.trim(),
        knowledgeBaseId: state.selectedKbId,
      );

      final botMsg = ChatMessage(
        id: 'bot_${DateTime.now().millisecondsSinceEpoch}',
        text: response.reply,
        isUser: false,
        ragUsed: response.ragUsed,
        timestamp: DateTime.now(),
      );

      emit(state.copyWith(
        messages: [...state.messages, botMsg],
        isTyping: false,
      ));
    } on RateLimitException catch (e) {
      emit(state.copyWith(isTyping: false));
      _startRateLimitCountdown(e.waitSeconds);
    } catch (e) {
      final errorMsg = ChatMessage(
        id: 'error_${DateTime.now().millisecondsSinceEpoch}',
        text: '❌ Error: ${e.toString()}',
        isUser: false,
        timestamp: DateTime.now(),
      );
      emit(state.copyWith(
        messages: [...state.messages, errorMsg],
        isTyping: false,
      ));
    }
  }

  void _startRateLimitCountdown(int seconds) {
    _rateLimitTimer?.cancel();
    emit(state.copyWith(rateLimitSeconds: () => seconds));

    _rateLimitTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      final remaining = (state.rateLimitSeconds ?? 0) - 1;
      if (remaining <= 0) {
        timer.cancel();
        emit(state.copyWith(rateLimitSeconds: () => null));
      } else {
        emit(state.copyWith(rateLimitSeconds: () => remaining));
      }
    });
  }

  void clearChat() {
    emit(ChatState(
      sessionId: 'sess_${Random().nextInt(999999)}',
      knowledgeBases: state.knowledgeBases,
      messages: [state.messages.first], // keep welcome message
    ));
  }

  @override
  Future<void> close() {
    _rateLimitTimer?.cancel();
    return super.close();
  }
}