import {AfterViewChecked, Component, ElementRef, ViewChild} from '@angular/core';
import {PromptInput} from './prompt-input/prompt-input';
import {MessageBox} from './message-box/message-box';
import {NewInput} from './new-input/new-input';
import {FeedbackButton} from './feedback-button/feedback-button';
import {WarningBugs} from './warning-bugs/warning-bugs';
import {VersionInfos} from './version-infos/version-infos';
import {LoadingNotification} from './loading-notification/loading-notification';

import {SourceBlock} from './source-block/source-block';
import {ChatbotConversation, ChatbotSource, ConversationsService} from '../services/conversations.service';


import {Store} from '@ngrx/store';
import {ActionTypes, StateInterface} from '../reducers';
import {FormsModule} from '@angular/forms';
import {ApiService} from '../services/api-service';
import {CommonModule} from '@angular/common';
import {ChatbotMessage, ChatbotMessageKind} from '../services/chatbot.message.type';
import {ToolsOptions} from './tools-options/tools-options';
import {TranslationService} from '../services/translation.service';
import {TimeSeparator} from './time-separator/time-separator';

@Component({
  selector: 'app-chatbot',
  imports: [
    PromptInput,
    MessageBox,
    NewInput,
    FeedbackButton,
    WarningBugs,
    VersionInfos,
    LoadingNotification,
    SourceBlock,
    FormsModule,
    CommonModule,
    ToolsOptions,
    TimeSeparator,
  ],
  templateUrl: './chatbot.html',
  styleUrl: './chatbot.scss'
})
export class Chatbot implements AfterViewChecked {
  public conversationsList: Array<ChatbotConversation> = [];
  public activeConversation: ChatbotConversation | null = null;
  public appVersion: string = '';
  public appState: any = '';
  conversationName: any;
  // fonctions d'exports
  visibleInput: boolean = false;
  // demo tour lors du premier chargement
  displayChipsTitleConversations = true;
  displayExportConversation: boolean = true;
  isExportDropdownActive: boolean = false;
  isExportSourcesDropdownActive: boolean = false;
  @ViewChild('conversationContainer') private conversationContainer: ElementRef | null = null;
  private shouldScrollToBottom: boolean = false;

  constructor(
    private conversations: ConversationsService,
    private apiService: ApiService,
    private store: Store<StateInterface>,
    private translationService: TranslationService
  ) {
    // Initialize conversations in the store
    this.store.dispatch({
      type: ActionTypes.UPDATE_CONVERSATIONS_LIST,
      payload: conversations.chatbotConversations
    });

    // Subscribe to conversations list from store
    this.store.select(state => state.conversationsList).subscribe(convList => {
      this.conversationsList = convList;
      if (!this.conversationsList.length) {
        this.newChat();
      }
    });

    // Subscribe to active conversation from store
    this.store.select(state => state.activeConversation).subscribe(activeConv => {
      if (activeConv && Object.keys(activeConv).length > 0) {
        const prevMessagesLength = this.activeConversation?.messages?.length || 0;
        this.activeConversation = activeConv as ChatbotConversation;
        const newMessagesLength = this.activeConversation?.messages?.length || 0;

        console.log('prevMessagesLength', prevMessagesLength, newMessagesLength);
        // Set flag to scroll to bottom when active conversation changes or when messages are added
        if (prevMessagesLength !== newMessagesLength) {
          this.shouldScrollToBottom = true;
        }
      } else if (this.conversationsList.length > 0) {
        this.updateActiveConversation(this.conversationsList[0]);
      }
    });

    // Get app version from store
    this.store.select(state => state.app.version).subscribe(version => {
      this.appVersion = version;
    });

    // Get app state from store
    this.store.select(state => state.app).subscribe(app => {
      this.appState = app;
    });

    // à désactiver en mode production
    this.demoConversation();
  }

  /**
   * Lifecycle hook that is called after the view has been checked
   * Used to scroll to the bottom of the conversation container when needed
   */
  ngAfterViewChecked(): void {
    if (this.shouldScrollToBottom && this.conversationContainer) {
      this.scrollToBottom();
      this.shouldScrollToBottom = false;
    }
  }

  /**
   * Translates a key using the translation service
   * @param key The key to translate
   * @param defaultValue Optional default value if translation is not found
   * @returns The translated string
   */
  translate(key: string, defaultValue?: string): string {
    return this.translationService.translate(key, defaultValue);
  }

  demoConversation() {


    // Add example sources if in demo mode
    if (this.appState.demoMode && this.activeConversation) {
      console.log('mode démo: on ajoute des demoConversation');
      // Create a proper instance of ChatbotConversation from the active conversation
      const updatedConversation: ChatbotConversation = ChatbotConversation.fromObject(this.activeConversation);

      this.addMockMessage("user");
      // Add three example sources


      const conversation2 = new ChatbotConversation();
      conversation2.name = "Liste de courses";
      conversation2.addMessage(new ChatbotMessage({
        kind: 'user',
        user: {},
        content: "Comment puis-je utiliser cette application?",
        name: "User"
      }));
      conversation2.addMessage(new ChatbotMessage({
        kind: 'llm',
        user: {},
        content: "The documents also highlight various post- incident safety measures implemented, including improved training procedures, enhanced maintenance protocols, and aircraft design modifications. Regulatory agencies such as the NTSB, BEA, AAIB, and others were involved in investigating these incidents and making safety recommendations. \n" +
          "This summary provides an overview of significant aviation incidents, their causes, and outcomes, which may be useful for understanding patterns in aircraft accidents and areas for improving aviation safety.\n" +
          "<br/>" +
          "Internet Search Not Activated.<br/>" +
          "No internet search was activated for this query<br/>" +
          "<br/>" +
          "Search results.",
        name: "Assistant"
      }));


      let source1 = new ChatbotSource();
      source1.title = "abc-1258.pdf";
      source1.url = "https://example.com/source1";
      source1.description = "Admittedly Air Traffic Control in smaller airports are being effected by ...";

      let source2 = new ChatbotSource();
      source2.title = "abc-45689.pdf";
      source2.url = "https://example.com/source1";
      source2.description = "DE GAGNE DATE: JANUARY 18, 2008 VEN #: V6-CAW-M2700-10 APPROVED BY: MARTIN SWAN DATE: FEBRUARY 5, 2008 -TITLE- DHC-6 ELEVATOR CONTROL CABLE WEAR SURVEY RESULTS ISSUE: 2 PAGE 2 respondents, representing 16 aircraft, operate outside the tropics and have a cycle/hour ratio of 1.6 to 2.8. Most respondents have reported that carbon steel elevator control cables are more wear resistant than stainless steel cables. Two operators in the tropics, representing 39 aircraft, use. \n" +
        "I remember having reconunended while dealing with the Guwahati crash in regard to a Vayudoot aircraft that the National Airports Authority should ensure that only trained and";

      conversation2.sources = [source1, source2, source2, source2, source2, source2, source2, source2, source2, source2, source2, source2, source2];


      // Update the active conversation in the store
      this.updateActiveConversation(updatedConversation);

      // Update the conversations list in the store
      const updatedList = this.conversationsList.map(conv =>
        conv === this.activeConversation ? updatedConversation : conv
      );

      updatedList.push(conversation2)

      this.store.dispatch({
        type: ActionTypes.UPDATE_CONVERSATIONS_LIST,
        payload: updatedList
      });

      // Set the first conversation as active
      this.updateActiveConversation(updatedConversation);
    }
  }

  updateActiveConversation(conversation: ChatbotConversation) {
    this.store.dispatch({
      type: ActionTypes.UPDATE_ACTIVE_CONVERSATION,
      payload: conversation
    });
  }

  addMockMessage(kind: ChatbotMessageKind, content?: string) {
    if (this.activeConversation) {
      // Create a proper instance of ChatbotConversation from the active conversation
      const updatedConversation = ChatbotConversation.fromObject(this.activeConversation);

      // Add the message to the copy
      updatedConversation.addMessage(new ChatbotMessage({
        kind: kind,
        user: {},
        content: content ? content : "blah",
        name: "Mock Message"
      }));

      // Update the active conversation in the store
      this.updateActiveConversation(updatedConversation);

      // Update the conversations list in the store
      const updatedList = this.conversationsList.map(conv =>
        conv === this.activeConversation ? updatedConversation : conv
      );

      this.store.dispatch({
        type: ActionTypes.UPDATE_CONVERSATIONS_LIST,
        payload: updatedList
      });

      // Set flag to scroll to bottom after adding a message
      this.shouldScrollToBottom = true;
    }
  }

  newChat() {
    const newConv = new ChatbotConversation();
    newConv.name = "Other conversation " + (this.conversationsList.length + 1);

    // Update the conversations list in the store by adding the new conversation to the existing list
    this.store.dispatch({
      type: ActionTypes.UPDATE_CONVERSATIONS_LIST,
      payload: [...this.conversationsList, newConv]
    });

    // Set the new conversation as active
    this.updateActiveConversation(newConv);
  }

  toggleSidePanelConversationsList() {
    this.store.dispatch({
      type: ActionTypes.UPDATE_APP,
      payload: {
        displayConversationListPanelLarge: !this.appState.displayConversationListPanelLarge
      }
    });
  }

  toggleSourcesPanel() {
    this.store.dispatch({
      type: ActionTypes.UPDATE_APP,
      payload: {
        displaySourcesPanelLarge: !this.appState.displaySourcesPanelLarge
      }
    });
  }

  launchDemoTour() {

  }

  endDemoTour() {

  }

  toggleExportDropdown() {
    this.isExportDropdownActive = !this.isExportDropdownActive;
    // Close the other dropdown if it's open
    if (this.isExportDropdownActive) {
      this.isExportSourcesDropdownActive = false;
    }
  }

  toggleExportSourcesDropdown() {
    this.isExportSourcesDropdownActive = !this.isExportSourcesDropdownActive;
    // Close the other dropdown if it's open
    if (this.isExportSourcesDropdownActive) {
      this.isExportDropdownActive = false;
    }
  }

  exportMessage() {
    // This method is kept for backward compatibility
    this.exportConversation('txt');
  }

  exportConversation(format: 'csv' | 'excel' | 'txt') {
    console.log(`Exporting conversation in ${format} format`);
    // Close the dropdown after selection
    this.isExportDropdownActive = false;

    if (!this.activeConversation) {
      console.error('No active conversation to export');
      return;
    }

    // Implementation will depend on the specific requirements
    // This is a placeholder for the actual export functionality
    switch (format) {
      case 'csv':
        // Export as CSV
        console.log('TODO Exporting as CSV');
        break;
      case 'excel':
        // Export as Excel
        console.log('TODO Exporting as Excel');
        break;
      case 'txt':
        // Export as TXT
        console.log('TODO Exporting as TXT');
        break;
    }
  }

  exportSources(format: 'csv' | 'excel' | 'txt') {
    console.log(`Exporting sources in ${format} format`);
    // Close the dropdown after selection
    this.isExportSourcesDropdownActive = false;

    if (!this.activeConversation || !this.activeConversation.sources || this.activeConversation.sources.length === 0) {
      console.error('No sources to export');
      return;
    }

    // Implementation will depend on the specific requirements
    // This is a placeholder for the actual export functionality
    switch (format) {
      case 'csv':
        // Export as CSV
        console.log('Exporting sources as CSV');
        break;
      case 'excel':
        // Export as Excel
        console.log('Exporting sources as Excel');
        break;
      case 'txt':
        // Export as TXT
        console.log('Exporting sources as TXT');
        break;
    }
  }

  copyToClipboard(text: string) {
    // Implementation for copying to clipboard
  }

  toggleVisibleEditInput(conversation: ChatbotConversation) {
    // Create a copy of the conversation
    const updatedConversation = ChatbotConversation.fromObject(conversation);

    // Toggle the visibleInput property
    updatedConversation.visibleInput = !conversation.visibleInput;

    // Update the active conversation if this is the active one
    if (this.activeConversation === conversation) {
      this.updateActiveConversation(updatedConversation);
    }

    // Update the single conversation in the store without replacing the entire list
    this.store.dispatch({
      type: ActionTypes.UPDATE_SINGLE_CONVERSATION,
      payload: {
        conversation: updatedConversation
      }
    });
  }

  changeTheme() {
    // Dispatch the action to switch to the next theme
    this.store.dispatch({type: ActionTypes.SWITCH_TO_NEXT_THEME});
  }

  changeLang() {
    // Dispatch the action to switch to the next language
    this.store.dispatch({type: ActionTypes.SWITCH_TO_NEXT_LANGUAGE});
  }

  pinConversation(conversation: ChatbotConversation) {
    conversation.pinned = !conversation.pinned;
  }

  copyConversationLink(conversation: ChatbotConversation) {
    console.log('todo copy conversation link', conversation);

  }

  deleteConversation(conversation: ChatbotConversation) {
    console.log('todo delete conversation', conversation);

  }

  /**
   * Scrolls to the bottom of the conversation container
   */
  private scrollToBottom(): void {
    try {
      const element = this.conversationContainer?.nativeElement;
      if (element) {
        element.scrollTop = element.scrollHeight;
      }
    } catch (err) {
      console.error('Error scrolling to bottom:', err);
    }
  }
}
