'use strict';

var binder = require('./binder.js');
var command = require('./command.js');
var stringResources = require('./stringResources.js');

var defaultOptions = {};
function replaceStringResources($aiDialogsWrapper) {
  if (!$aiDialogsWrapper) {
    return;
  }
  var labels = $aiDialogsWrapper.find(".trv-replace-string");
  var ariaLabel = $aiDialogsWrapper.find("[aria-label]").add($aiDialogsWrapper);
  var titles = $aiDialogsWrapper.find("[title]");
  if (labels.length) {
    Array.from(labels).forEach((element) => {
      replaceText($(element));
    });
  }
  if (ariaLabel.length) {
    Array.from(ariaLabel).forEach((element) => {
      replaceAttribute($(element), "aria-label");
    });
  }
  if (titles.length) {
    Array.from(titles).forEach((element) => {
      replaceAttribute($(element), "title");
    });
  }
}
function replaceText($el) {
  if ($el) {
    $el.text(stringResources.stringResources[$el.text()]);
  }
}
function replaceAttribute($el, attribute) {
  if ($el) {
    $el.attr(attribute, stringResources.stringResources[$el.attr(attribute)]);
  }
}
class AiPrompt {
  constructor(element, options, viewerOptions) {
    this.options = $.extend({}, defaultOptions, options);
    this.viewerOptions = viewerOptions;
    this.controller = this.options.controller;
    if (!this.controller) {
      throw "No controller (telerikReporting.ReportViewerController) has been specified.";
    }
    this.notificationService = this.options.notificationService;
    if (!this.notificationService) {
      throw "No notificationService (telerikReporting.NotificationService) has been specified.";
    }
    this.element = element;
    this.$element = $(element);
    this.kendoAiConsentDialog;
    this.kendoAiPromptDialog;
    this.kendoAiPrompt;
    this.kendoAiPromtDialogLocation;
    this.reportViewerWrapper = $(`[data-selector='${this.viewerOptions.viewerSelector}']`);
    this.pagesAreaContainer = this.reportViewerWrapper.find('[data-id="trv-pages-area"]');
    this.aiPromptDialogInitialized = false;
    this.aiPromptInitialized = false;
    this.requireConsent = false;
    this.allowCustomPrompts = true;
    this.predefinedPrompts = [];
    this.init();
  }
  init() {
    if (this.aiPromptDialogInitialized) {
      return;
    }
    replaceStringResources(this.$element);
    this._initAiConsentDialog();
    this._attachAiConsentDialogCommands();
    this._initAiPromptDialog();
    this._attachEvents();
    this.aiPromptDialogInitialized = true;
  }
  _attachEvents() {
    this.controller.on("beginLoadReport", this.close.bind(this)).on("viewModeChanged", this.close.bind(this));
    this.notificationService.setAiPromptDialogVisible((event, args) => {
      this.toggleAiPromptDialog(args.visible);
    }).setSendEmailDialogVisible((event, args) => {
      if (args.visible && this.controller.getAiPromptInitiated()) {
        this.close();
      }
    });
    $(window).on("resize", () => {
      if (this.kendoAiPromptDialog && this.kendoAiPromptDialog.options.visible) {
        this.storeDialogPosition();
        this.adjustDialogPosition(this.kendoAiPromptDialog);
      }
    });
  }
  _attachAiConsentDialogCommands() {
    const optionsCommandSet = {
      "aiConsent_Cancel": new command.Command(() => {
        this.kendoAiConsentDialog.close();
        this.notificationService.setAiPromptDialogVisible({
          visible: false
        });
      }),
      "aiConsent_Accept": new command.Command(() => {
        this.kendoAiConsentDialog.close();
        this.controller.saveToSessionStorage("trvAiConsent", "true");
        this.controller.setAiPromptInitiated(true);
        if (this.kendoAiPromptDialog) {
          this._initAiPrompt(this.predefinedPrompts);
          this.kendoAiPromptDialog.open();
        }
      })
    };
    binder.Binder.attachCommands(this.kendoAiConsentDialog.element.find(".trv-ai-consent-actions"), optionsCommandSet, this.viewerOptions);
  }
  _initAiConsentDialog() {
    const aiConsentDialogElement = this.element.querySelector(".trv-ai-consent-dialog");
    if (!aiConsentDialogElement) {
      console.warn('Failed to initialize AI consent dialog due to missing element with class "trv-ai-consent-dialog".');
      return;
    }
    this.kendoAiConsentDialog = new kendo.ui.Window(aiConsentDialogElement, {
      title: stringResources.stringResources["aiPromptDialogConsentTitle"] || "",
      width: 500,
      minWidth: 400,
      minHeight: 106,
      maxHeight: 800,
      resizable: false,
      scrollable: true,
      open: (event) => {
        this.adjustDialogPosition(this.kendoAiConsentDialog);
      }
    });
    this.kendoAiConsentDialog.element.removeClass("trv-ai-consent-dialog k-hidden");
    this.kendoAiConsentDialog.wrapper.addClass("trv-ai-consent-dialog");
  }
  _initAiPromptDialog() {
    const aiPromptDialogElement = this.element.querySelector(".trv-ai-prompt-dialog");
    if (!aiPromptDialogElement) {
      console.warn('Failed to initialize AI prompt dialog due to missing element with class "trv-ai-prompt-dialog".');
      return;
    }
    this.kendoAiPromptDialog = new kendo.ui.Window(aiPromptDialogElement, {
      title: false,
      visible: false,
      draggable: {
        dragHandle: ".k-prompt-header"
      },
      height: "fit-content",
      width: 500,
      minWidth: 400,
      maxHeight: 800,
      scrollable: true,
      close: (event) => {
        this.storeDialogPosition();
      },
      open: (event) => {
        this.adjustDialogPosition(this.kendoAiPromptDialog);
      },
      deactivate: (event) => {
        this.notificationService.setAiPromptDialogVisible({
          visible: false
        });
      }
    });
    this.kendoAiPromptDialog.element.removeClass("trv-ai-prompt-dialog k-hidden");
    this.kendoAiPromptDialog.wrapper.addClass("trv-ai-prompt-dialog");
  }
  _initAiPrompt(promptSuggestions) {
    if (this.aiPromptInitialized) {
      this.kendoAiPrompt.setOptions({
        promptSuggestions
      });
      this.kendoAiPrompt.activeView(this.kendoAiPrompt.activeView());
    } else {
      const aiPromptElement = this.kendoAiPromptDialog?.element?.find("#trv-ai-prompt");
      if (!aiPromptElement) {
        console.warn('Failed to initialize AI prompt dialog due to missing element with id "trv-ai-prompt".');
        return;
      }
      const that = this;
      this.kendoAiPrompt = new kendo.ui.AIPrompt(aiPromptElement, {
        activeView: 0,
        promptRequest: function(event) {
          if (!event.prompt) {
            this.activeView(0);
            return;
          }
          that.controller.getAIResponse(event.prompt).then((response) => {
            this.addPromptOutput(that.createPromptOutputFromResponse(response, event));
            this.activeView(1);
          }).catch((error) => {
            this.addPromptOutput(that.createPromptOutputFromResponse(error?._responseJSON?.exceptionMessage || error?._responseJSON?.ExceptionMessage, event));
            this.activeView(1);
          });
        },
        toolbarItems: [
          { type: "spacer" },
          { type: "button", icon: "x", fillMode: "flat", themeColor: "primary", click: (e) => {
            this.close();
          } }
        ],
        promptSuggestions,
        views: [
          {
            type: "prompt",
            messages: {
              promptPlaceholder: "Enter your prompt"
            }
          },
          {
            type: "output"
          }
        ]
      });
      this.aiPromptInitialized = true;
    }
    this.disableAiPromptTextArea(promptSuggestions && promptSuggestions.length > 0);
    const aiPromptToolbar = this.kendoAiPrompt.element.find(".k-prompt-header .k-toolbar").data("kendoToolBar");
    aiPromptToolbar && aiPromptToolbar.bind("toggle", (e) => {
      if (e.target.text() === "Ask AI") {
        this.disableAiPromptTextArea(promptSuggestions && promptSuggestions.length > 0);
      }
    });
  }
  disableAiPromptTextArea(hasPromptSuggestions) {
    if (this.allowCustomPrompts) {
      return;
    }
    let aiPromptTextAreaPlaceholder = stringResources.stringResources["aiPromptDialogTextAreaPlaceholder"];
    const aiPromptTextArea = this.kendoAiPrompt.element.find(".k-prompt-content .k-prompt-view textarea");
    if (!hasPromptSuggestions) {
      const aiPromptGenerateButton = this.kendoAiPrompt.element.find(".k-prompt-footer .k-actions");
      aiPromptGenerateButton && aiPromptGenerateButton.addClass("k-disabled");
      aiPromptTextAreaPlaceholder = stringResources.stringResources["aiPromptDialogNoPredefinedAndCustomPromptsPlaceholder"] || "";
    } else {
      aiPromptTextAreaPlaceholder = stringResources.stringResources["aiPromptDialogNoCustomPromptsPlaceholder"] || "";
    }
    aiPromptTextArea && aiPromptTextArea.attr("placeholder", aiPromptTextAreaPlaceholder) && aiPromptTextArea.addClass("k-disabled");
  }
  storeDialogPosition() {
    this.kendoAiPromtDialogLocation = this.kendoAiPromptDialog.wrapper.offset();
  }
  adjustDialogPosition(dialog) {
    var windowWidth = $(window).innerWidth();
    var windowHeight = $(window).innerHeight();
    var width = dialog.wrapper.outerWidth(true);
    var height = dialog.wrapper.outerHeight(true);
    var padding = 10;
    var scrollOverlapOffsetX = 10;
    if (!this.kendoAiPromtDialogLocation) {
      var reportViewerCoords = this.pagesAreaContainer[0].getBoundingClientRect();
      dialog.setOptions({
        position: {
          // scrollY ensures that the dialog appears at the correct place even when the viewer is rendered inside a scrollable page
          top: reportViewerCoords.top + padding + window.scrollY,
          left: reportViewerCoords.right - width - padding - scrollOverlapOffsetX
        }
      });
    } else {
      var left = this.kendoAiPromtDialogLocation.left;
      var top = this.kendoAiPromtDialogLocation.top;
      var right = left + width;
      var bottom = top + height;
      if (right > windowWidth - padding) {
        left = Math.max(padding, windowWidth - width - padding);
        dialog.setOptions({
          position: {
            left
          }
        });
      }
      if (bottom > windowHeight - padding) {
        top = Math.max(padding, windowHeight - height - padding);
        this.kendoAiPromptDialog.setOptions({
          position: {
            top
          }
        });
      }
    }
  }
  toggleAiPromptDialog(show) {
    if (show) {
      this.open();
    } else {
      this.close();
    }
  }
  open() {
    this.controller.createAIThread().then((data) => {
      this.predefinedPrompts = data?.predefinedPrompts;
      this.allowCustomPrompts = data?.allowCustomPrompts;
      if (this.kendoAiConsentDialog && data.requireConsent && this.controller.loadFromSessionStorage("trvAiConsent") !== "true") {
        $(".trv-ai-consent-content").html(data?.consentMessage);
        this.kendoAiConsentDialog.open();
        return;
      }
      if (this.kendoAiPromptDialog) {
        this.controller.setAiPromptInitiated(true);
        this._initAiPrompt(this.predefinedPrompts);
        this.kendoAiPromptDialog.open();
      }
    });
  }
  close() {
    this.controller.setAiPromptInitiated(false);
    if (this.kendoAiConsentDialog) {
      this.kendoAiConsentDialog.close();
    }
    if (this.kendoAiPromptDialog && this.kendoAiPromptDialog.options.visible) {
      this.kendoAiPromptDialog.close();
    }
  }
  createPromptOutputFromResponse(response, promptData) {
    return {
      id: kendo.guid(),
      output: response,
      prompt: promptData.prompt,
      isRetry: promptData.isRetry
    };
  }
}

exports.AiPrompt = AiPrompt;
