;; The all-powerful Org mode

(use-package org
  :straight '(org-plus-contrib :type git
              :repo "https://git.sr.ht/~bzg/org-contrib")
  :mode (("\\.org\\'" . org-mode))
  :init
  (leader-def-key "o" '(nil :which-key "org"))
  :config
  (add-hook 'org-mode-hook #'auto-fill-mode)
  (add-hook 'org-mode-hook (lambda () (require 'org-attach)))
  (defun org-find-daily-note ()
    (interactive)
    (let* ((filename (expand-file-name
                      (format "~/org/daily/%s.org"
                              (format-time-string "%Y-%m-%d"))))
           (file-exists (file-exists-p filename)))
      (find-file filename)
      (goto-char (point-min))
      (unless file-exists
        (insert (format "* %s daily note"
                        (format-time-string "%Y-%m-%d")))
        (newline))
      (goto-char (point-max))))
  :custom
  (org-agenda-files `(,(expand-file-name "~/org/todo.org")
                      ,(expand-file-name "~/org/daily")))
  (org-todo-keywords '((sequence
                        "TODO(t)"
                        "IN PROGRESS(i)"
                        "BLOCKED(b)"
                        "|"
                        "DONE(d)"
                        "CANCELLED(c)")))
  (org-capture-templates `(("d" "Daily note" plain
                            (function org-find-daily-note)
                            "* %<%I:%M %p>")
                           ("s" "Spotify task" entry
                            (file+headline ,(expand-file-name "~/org/todo.org") "Spotify")
                            "* TODO %i%?")
                           ("p" "Personal task" entry
                            (file+headline ,(expand-file-name "~/org/todo.org") "Personal")
                            "* TODO %i%?")))
  (org-return-follows-link t)
  (org-ellipsis " ▼")
  (org-src-fontify-natively t)
  (org-log-done 'time)
  (org-agenda-custom-commands '(("t" "TODOs"
                                 ((agenda)
                                  (alltodo)))))
  (org-agenda-span 'day)
  (org-agenda-todo-ignore-scheduled 'future)
  (org-agenda-tags-todo-honor-ignore-options t)
  (org-file-apps '(("log" . emacs)
                   (auto-mode . emacs)
                   (directory . emacs)
                   ("\\.pdf\\'" . emacs)
                   ("\\.mm\\'" . default)
                   ("\\.x?html?\\'" . default)))
  :general
  (leader-map "oa" #'org-agenda)
  (leader-map "oc" #'org-capture)
  (leader-map "ol" #'org-store-link)
  (leader-map "od" #'org-find-daily-note)
  (normal org-mode-map "<return>" #'org-return)
  (normal org-mode-map "T" #'org-insert-todo-heading))

(use-package evil-org
  :after org
  :hook ((org-mode . evil-org-mode)
         (org-agenda-mode . (lambda ()
                              (require 'evil-org-agenda)
                              (evil-org-agenda-set-keys)))))

(use-package org-super-agenda
  :after (org)
  :defer 1
  :config
  (org-super-agenda-mode)
  ;; Nuke the header keybindings
  (setq org-super-agenda-header-map (make-sparse-keymap))
  :custom
  (org-super-agenda-groups `((:name "In progress"
                              :todo "IN PROGRESS")
                             (:name "Daily"
                              :file-path ,(expand-file-name "~/org/daily"))
                             (:name "Spotify"
                              :tag "@spotify")
                             (:name "Lola"
                              :tag "@lola")
                             (:name "unifyDB"
                              :tag "@unifydb")
                             (:name "Personal"
                              :tag "@personal")
                             (:name "Jira" :file-path ,(expand-file-name "~/org/jira")))))

;; (use-package org-gcal
;;   :commands (org-gcal-sync
;;              org-gcal-fetch
;;              org-gcal-post-at-point
;;              org-gcal-delete-at-point
;;              org-gcal-request-token)
;;   :after (org evil-org)
;;   :init
;;   (defun org-agenda-redo-and-fetch-gcal (&optional all)
;;     (interactive "P")
;;     (let ((cb (if all #'org-agenda-redo-all #'org-agenda-redo)))
;;       (deferred:nextc (org-gcal-fetch) cb)))
;;   (advice-add 'evil-org-agenda-set-keys :after
;;               (lambda ()
;;                 (general-def 'motion org-agenda-mode-map
;;                   "gR" #'org-agenda-redo-and-fetch-gcal)))
;;   :config
;;   (setq org-gcal-client-id (password-store-get "lola-org-gcal-client-id")
;;         org-gcal-client-secret (password-store-get "lola-org-gcal-client-secret")
;;         org-gcal-fetch-file-alist `(("jeremydormitzer@lola.com" .
;;                                      ,(expand-file-name "~/org/lola-gcal.org"))
;;                                     ("jeremy.dormitzer@gmail.com" .
;;                                      ,(expand-file-name "~/org/personal-gcal.org"))
;;                                     ("lut2o2moohg6qkdsto1qfq7th4@group.calendar.google.com" .
;;                                      ,(expand-file-name "~/org/j-n-gcal.org")))
;;         org-gcal-notify-p nil))

;; (use-package org-jira
;;   :after (org)
;;   :init
;;   (setq jiralib-url "https://lola.atlassian.net"
;;         org-jira-working-dir (expand-file-name "~/org/jira")
;;         org-jira-jira-status-to-org-keyword-alist '(("To Do" . "TODO")
;;                                                     ("Blocked" . "BLOCKED")
;;                                                     ("In Progress" . "IN PROGRESS")
;;                                                     ("Code Review" . "IN PROGRESS")
;;                                                     ("Awaiting Release" . "IN PROGRESS")
;;                                                     ("Done" . "DONE")
;;                                                     ("Won't Fix" . "CANCELLED")))
;;   (add-to-list 'org-agenda-files org-jira-working-dir))

;; org-roam provides backlinks between org documents
(use-package org-roam
  :hook ((org-mode . org-roam-db-autosync-mode))
  :custom
  (org-roam-directory "~/org")
  (org-roam-list-files-commands '(rg find fd fdfind))
  :init
  (setq org-roam-v2-ack t)
  (defvar org-roam-commands-map (make-sparse-keymap))
  (general-def org-roam-commands-map
    "l" #'org-roam-buffer-toggle
    "f" #'org-roam-node-find
    "i" #'org-roam-node-insert
    "I" #'org-roam-node-insert-immediate)
  (with-eval-after-load 'org
    (general-def org-mode-map "C-c n" org-roam-commands-map)
    ;; (which-key-declare-prefixes-for-mode 'org-mode "C-c n" "org-roam")
    )
  :general
  (leader-map "of" #'org-roam-node-find)
  :config
  (general-def 'normal org-roam-backlinks-mode-map
    "RET" #'org-open-at-point
    "q" #'bury-buffer))

(provide 'init-org)