;; -*- lexical-binding: t -*-


;;;; circe
(defvar jao-libera-channels ())
(defvar jao-oftc-channels ())
(defvar jao-bitlbee-channels ())
(defvar jao-slack-channels ())

(use-package circe
  :ensure t
  :bind (:map circe-channel-mode-map
              (("C-c C-a" . lui-track-jump-to-indicator)))
  :init
  (setq circe-chat-buffer-name "{target} - {network}"
        circe-default-realname "https://jao.io"
        circe-default-part-message ""
        circe-default-quit-message ""
        circe-ignore-list nil
        circe-server-coding-system '(undecided . undecided)
        circe-server-killed-confirmation 'ask-and-kill-all
        circe-server-auto-join-default-type :after-auth
        circe-server-buffer-name "{network} - {host}:{port}"
        circe-format-say "({nick}) {body}"
        circe-format-self-say "(jao) {body}"
        circe-new-buffer-behavior 'ignore
        circe-new-buffer-behavior-ignore-auto-joins t
        circe-nickserv-ghost-style 'after-auth
        circe-prompt-string ": "
        circe-completion-suffix ", "
        circe-reduce-lurker-spam t

        circe-lagmon-mode-line-format-string "" ;;  "%.0f "
        circe-lagmon-mode-line-unknown-lag-string "" ;; "? "
        circe-lagmon-timer-tick 120
        circe-lagmon-reconnect-interval 180

        lui-max-buffer-size 30000
        lui-fill-column 80
        lui-time-stamp-position 'right
        lui-time-stamp-format "%H:%M"
        lui-flyspell-p nil

        lui-track-indicator (if window-system 'fringe 'bar)
        lui-track-behavior 'before-tracking-next-buffer)
  :config

  (defsubst jao-circe-nick-no ()
    (if (derived-mode-p 'circe-query-mode)
        2
      (length (circe-channel-nicks))))

  (defsubst jao-circe-netowrk ()
    (or (plist-get lui-logging-format-arguments :network) ""))

  (define-minor-mode jao-circe-user-number-mode ""
    :lighter (:eval (format " [%s]" (jao-circe-nick-no))))

  (defun jao-circe-channel-hook ()
    (when jao-mode-line-in-minibuffer
      (setq header-line-format
            '(" %b" (:eval (format "@%s - %s nicks"
                                   (jao-circe-netowrk)
                                   (jao-circe-nick-no))))))
    (jao-circe-user-number-mode 1))

  (add-hook 'circe-channel-mode-hook #'jao-circe-channel-hook)
  (add-hook 'circe-query-mode-hook #'jao-circe-channel-hook)

  (defun circe-command-RECOVER (&rest _ignore)
    "Recover nick"
    (jao-with-auth "freenode" u p
      (circe-command-MSG "nickserv" (format "IDENTIFY %s %s" u p))
      (circe-command-MSG "nickserv" (format "GHOST %s" u))
      (circe-command-MSG "nickserv" (format "RELEASE %s" u))
      (circe-command-NICK u)))

  (defun circe-command-NNICKS (&rest _)
    "Echo number of nicks"
    (circe-display-server-message
     (format "%d nicks in this channel" (jao-circe-nick-no))))

  (defun circe-command-SENDFILE (line)
    "/sendfile for localslackirc"
    (circe-command-QUOTE (format "sendfile %s" line)))

  (advice-add 'circe-command-NAMES :after #'circe-command-NNICKS)

  (defun jao-circe-reconnect-unmonitored ()
    (interactive)
    (dolist (b (buffer-list))
      (with-current-buffer b
        (when (and (derived-mode-p 'circe-server-mode)
                   circe-lagmon-disabled)
          (circe-reconnect)))))

  (add-to-list 'jao-sleep-awake-functions #'jao-circe-reconnect-unmonitored)

  (setq circe-network-options
        (list (jao-with-auth "libera" u p
                (list "Libera Chat" :nick u :channels jao-libera-channels
                      :tls t :sasl-username u :sasl-password p))
              (jao-with-auth "oftc" u p
                (list "OFTC"
                      :nick u :channels jao-oftc-channels :nickserv-password p
                      :tls t :sasl-username u :sasl-password p))
              (jao-with-auth "bitlbee" u p
                (list "Bitlbee" :host "127.0.0.1" :nick u
                      :channels jao-bitlbee-channels :lagmon-disabled t
                      :nickserv-password u :user p))))

  (jao-shorten-modes 'circe-channel-mode
                     'circe-server-mode
                     'circe-query-mode)

  (enable-circe-display-images)
  (enable-lui-track)
  (circe-lagmon-mode))

;;;; startup
(defun jao-chats (&optional p)
  (interactive "P")
  (when (or p (y-or-n-p "Connect to telegram? "))
    (telega))
  (when (and (fboundp 'ement-connect) (or p (y-or-n-p "Connect to matrix? ")))
    (unless (get-buffer "*Ement Rooms*")
      (jao-with-auth "matrix.org" u p (ement-connect :user-id u :password p))))
  ;; (when (and (fboundp 'mastodon) (or p (y-or-n-p "Connect to mastodon? ")))
  ;;   (mastodon))
  (dolist (c '(("Libera Chat" . "irc.libera.chat:6697")))
    (unless (get-buffer (cdr c))
      (when (or p (y-or-n-p (format "Connect to %s? " (car c))))
        (circe (car c))))))

(defun jao-all-chats ()
  (interactive)
  (when jao-tracking-use-scratch
    (jao-afio-goto-chats)
    (delete-other-windows))
  (jao-chats t))

(defun jao-chats-telega ()
  (interactive)
  (jao-buffer-same-mode '(telega-root-mode telega-chat-mode)))

(defun jao-chats-slack ()
  (interactive)
  (jao-buffer-same-mode 'slack-message-buffer-mode))

(defun jao-chats-irc ()
  (interactive)
  (jao-buffer-same-mode '(circe-channel-mode circe-query-mode erc-mode)))

;;;; consult narrowing
(defvar jao-chat-buffer-source
  (list :name "chats"
        :category 'buffer
        :action (lambda (b) (jao-afio-pop-to-buffer 0 b))
        :hidden t
        :narrow (cons ?c "chats")
        :items (jao-consult--mode-buffers 'erc-mode
                                          'circe-channel-mode
                                          'circe-query-mode
                                          'signel-chat-mode
                                          'slack-message-buffer-mode
                                          'slack-thread-message-buffer-mode
                                          'telega-root-mode
                                          'telega-chat-mode
                                          'ement-room-mode
                                          'ement-room-list-mode)))
(with-eval-after-load "consult"
  (jao-consult-add-buffer-source 'jao-chat-buffer-source))


(provide 'jao-custom-chats)
