(in-package #:cl-deck-builder2.web)

(defvar *icon-file-types*
  (mapcar #'pathname-name
          (mapcar (lambda (x) (uiop:enough-pathname x (merge-pathnames "img/file-icons-classic/" cl-deck-builder2.config::*static-directory*)))
                  (uiop:directory-files (merge-pathnames "img/file-icons-classic/" cl-deck-builder2.config::*static-directory*)))))

(defun icon-or-url (file-url)
  (let ((ext (pathname-type file-url))
        (thumbnails-allowed '("gif" "jpeg" "jpg" "png" "svg" "webp")))
    (cond
      ((member ext thumbnails-allowed :test #'equal) file-url)
      ((member ext *icon-file-types* :test #'equal)
       (merge-pathnames
        (make-pathname :directory "img/file-icons-classic" :name ext :type "svg")
        cl-deck-builder2.config::*static-directory*))
      (t "/img/file-icons-classic/bin.svg"))))

(defun render-upload-index-old ()
  "Helper Function. The purpose of RENDER-UPLOAD-INDEX is to generate a list of file information and thumbnail info from The files in the MITO-ATTACHMENT system.

This is pretty crazy and probably needs to be unpacked into a few components:

IMAGES: SELECT-DAO 'ATTACHMENT. This could probably just be something like GET-ATTACHMENTS.

ICON-OR-URL: This component decides wether or not a provided URL might be a: JPG, PNG, GIF, SVG, etc., Binary File, or something we have icons for.

THUMBNAILS-ALLOWED The supported viewable file types we want to forward straight to the web interface.

ICON-EXISTS could probably use STATIC-PROBE-FILE-LIST.

Then the final PLIST at the end could be similar to YDK-TO-TEMPLATE-DATA. ATTACHMENT-PLIST?

We use icons from [dmhendricks/file-icon-vectors](https://github.com/dmhendricks/file-icon-vectors)."
  (let ((images (select-attachment)))
    (let ((files (mapcar
                  (lambda (image)
                    (let* ((url (mito-attachment:file-url image))
                           (icon (icon-or-url url)))
                      `((:id . ,(mito:object-id image))
                        (:url . ,url)
                        (:icon . ,icon)
                        (:attachment . ,image))))
                  images)))
      )))

(defun %images-to-plist (&rest images)
  (let ((lst '()))
    (dolist (image images (reverse lst))
      (let ((file-url (mito-attachment:file-url image)))
        (push `((:id . ,(mito:object-id image))
                (:url . ,file-url)
                (:icon . ,(icon-or-url file-url))
                (:attachment . ,image))
              lst)))))
      
(defun render-upload-index ()
  (let* ((images (select-attachment))
         (files (apply #'%images-to-plist images)))
    (render-with-env #P"upload.html"
                     `(:active "/upload"
                       :files ,files
                       :length  ,(length images)))))

(defroute ("/upload" :method :GET) ()
  "File Uploader Main Route."
  (v:info :upload "GET /upload")

  (with-logged-in-user
    (render-upload-index)))

(defroute ("/upload" :method :POST) (&key _parsed)
  "File Uploader POST processing Route.

TODO Can this be merged with YDK uploader?"
  (v:info :upload "POST /upload => ~a" _parsed)

  (with-logged-in-user
    (let ((files (query-param "files" _parsed)))
      (dolist (file files)
        (destructuring-bind (content filename content-type)
            file
          (let ((success (create-attachment content filename content-type)))
            (if success
                (flash-message (format nil (_ "Upload success! <a href=\"~a\">~a</a>")
                                       (mito-attachment:file-url success)
                                       (mito-attachment:file-url success)))
                (flash-error (_ "Error uploading file. Try again?")))))))
    (render-upload-index)))

(defroute ("/upload/:id" :method :DELETE) (&key id)
  "Remove an ATTACHMENT from the database using DELETE-BY-VALUES for ATTACHMENT by ID."
  (v:info :upload "DELETE /upload/~d" id)

  (with-logged-in-user
    (handler-case
        (ratify:with-parsed-forms
            ((:integer id))
          (let ((found (find-dao 'attachment :id id)))
            (if found
                (delete-by-values 'attachment :id id)
                (progn
                  (flash-error (format nil (_ "No such attachment #~d") id))
                  (redirect "/upload" 400)))))
      (ratify:combined-error (e)
        (flash-error e)
        (redirect "/upload" 400)))))
