import { Builder } from "builder-pattern";
import * as Handlebars from "handlebars";
import * as log from "loglevel";
import { ChatController } from "./controller/ChatController";
import { UserController } from "./controller/UserController";
import { ChatModel } from "./model/ChatModel";
import { ChatModelHelper } from "./model/ChatModelHelper";
import { UserModel } from "./model/UserModel";
import { AlertifyNotificationService } from "../common/service/AlertifyNotificationService";
import { EncryptionServiceFactory } from "../common/service/EncryptionServiceFactory";
import { FuseSearchService } from "../common/service/FuseSearchService";
import { MarkDownItMarkDownService } from "../common/service/MarkDownItMarkDownService";
import { NotificationService } from "../common/service/NotificationService";
import { SearchService } from "../common/service/SearchService";
import { TemplateFactory } from "./template/TemplateFactory";
import { ChatView } from "./view/ChatView";
import { ChatViewDeps } from "./view/ChatViewDeps";
import { UserView } from "./view/UserView";
import { UserViewDeps } from "./view/UserViewDeps";
import { ActiveUserViewModel } from "./viewmodel/ActiveUserViewModel";
import moment = require("moment");

// log.setLevel("TRACE");

const usersListElement = document.getElementById("contacts-box");
const userSearchButton = document.getElementById("user-search");
const userSearchInputElement = document.getElementById(
  "user-search-term"
) as HTMLInputElement;
const userSearchCancelButton = document.getElementById("user-search-cancel");
const chatArea = document.getElementById("chat-area-new");

const activeUserSearchService: SearchService<ActiveUserViewModel> = new FuseSearchService(
  ["userName"]
);
const ns: NotificationService = new AlertifyNotificationService();
const encryptionService = EncryptionServiceFactory.getEncryptionService();

const chatModelHelper = new ChatModelHelper(encryptionService, ns);
const chatModel = new ChatModel(chatModelHelper);
const userModel = new UserModel(ns);
const cvDeps: ChatViewDeps = {
  chatModel: chatModel,
  // @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
  messageContainer: chatArea,
  messageSendTemplate: TemplateFactory.getTemplate(
    "msg_container_send_template"
  ),
  messageReceiveTemplate: TemplateFactory.getTemplate("msg_container_template"),
  markdownService: new MarkDownItMarkDownService(),
  encryptionService: encryptionService,
  notificationService: ns,
  userModel: userModel,
};
const chatView = new ChatView(cvDeps);
chatModel.attach(chatView);
const chatController = new ChatController(chatModel, chatView);

const uvDeps: UserViewDeps = {
  model: userModel,
  chatModel: chatModel,
  // @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
  usersListElement: usersListElement,
  userSearchInputElement: userSearchInputElement,
  // @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
  userSearchButton: userSearchButton,
  // @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
  userSearchCancelButton: userSearchCancelButton,
  searchService: activeUserSearchService,
  userContactOnlineTemplate: TemplateFactory.getTemplate(
    "user-contact-online-template"
  ),
  userContactOfflineTemplate: TemplateFactory.getTemplate(
    "user-contact-offline-template"
  ),
  notificationService: ns,
};
const userView = new UserView(uvDeps);
userModel.attach(userView);
const userController = new UserController(userModel, userView);
userController.getActiveUsers();

// @ts-ignore
Handlebars.registerHelper("moment", require("helper-moment"));
Handlebars.registerHelper("avatar", function () {
  return '<div class="img_cont_msg"> <img src="https://static.turbosquid.com/Preview/001292/481/WV/_D.jpg" class="rounded-circle user_img_msg"> </div>';
});
Handlebars.registerHelper("fromNow", function (date: string) {
  if (date == null) return ": Never";
  return moment(date).fromNow();
});
Handlebars.registerHelper("msgDateFormat", function (date: string) {
  return moment(date).calendar(moment.now(), {
    lastWeek: "DD/MM/YY hh:mm A",
    sameElse: "DD/MM/YY hh:mm A",
  });
});

Handlebars.registerHelper("lockIcon", function (unlocked: boolean) {
  switch (unlocked) {
    case true: {
      return '<i class="fas fa-lock-open"></i>';
    }
    default: {
      return '<i class="fas fa-lock"></i>';
    }
  }
});

ns.success("Welcome");
// ns.errorWithDelay("Hmm very long error notif", 10);

const test = Builder<UserViewDeps>().build();
