local DataStorage = require("datastorage")
local DocSettings = require("frontend/docsettings")
local ReadHistory = require("readhistory")
local FFIUtil = require("ffi/util")
local Ftp = require("apps/cloudstorage/ftp")
local FtpApi = require("apps/cloudstorage/ftpapi")
local InfoMessage = require("ui/widget/infomessage")
local LuaSettings = require("frontend/luasettings")
local UIManager = require("ui/uimanager")
local NetworkMgr = require("ui/network/manager")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local logger = require("logger")
local util = require("util")
local _ = require("gettext")
local T = FFIUtil.template

local Send2Ebook = WidgetContainer:new{}

local initialized = false
local wifi_enabled_before_action = true
local send2ebook_config_file = "send2ebook_settings.lua"
local config_key_custom_dl_dir = "custom_dl_dir";
local default_download_dir_name = "send2ebook"
local download_dir_path
local send2ebook_settings

function Send2Ebook:downloadFileAndRemove(connection_url, remote_path, local_download_path)
    local url = connection_url .. remote_path
    local response = FtpApi:downloadFile(url)

    if response ~= nil then
        local_download_path = util.fixUtf8(local_download_path, "_")
        local file = io.open(local_download_path, "w")
        file:write(response)
        file:close()
        FtpApi:delete(url)
        return 1
    else
        logger.err("Send2Ebook: Error. Invalid connection data? ")
        return 0
    end
end

-- TODO: implement as NetworkMgr:afterWifiAction with configuration options
function Send2Ebook:afterWifiAction()
    if not wifi_enabled_before_action then
        NetworkMgr:promptWifiOff()
    end
end

function Send2Ebook:init()
    self.ui.menu:registerToMainMenu(self)
end

function Send2Ebook:addToMainMenu(menu_items)
    self:lazyInitialization()
    menu_items.send2ebook = {
        text = _("Send2Ebook (Receiver)"),
        sub_item_table = {
            {
                text = _("Download and remove from server"),
                callback = function()
                  if not NetworkMgr:isOnline() then
                      wifi_enabled_before_action = false
                      NetworkMgr:beforeWifiAction(self.process)
                  else
                      self:process()
                  end
                end,
            },
            {
                text = _("Go to download folder"),
                callback = function()
                    local FileManager = require("apps/filemanager/filemanager")
                    if FileManager.instance then
                        FileManager.instance:reinit(download_dir_path)
                    else
                        FileManager:showFiles(download_dir_path)
                    end
                end,
            },
            {
                text = _("Remove read (opened) articles"),
                callback = self.removeReadActicles,
            },
            {
                text = _("Set custom download directory"),
                callback =  self.setCustomDownloadDirectory,
            },
            {
                text = _("Settings"),
                callback = self.editFtpConnection,
            },
            {
                text = _("Help"),
                callback = function()
                    UIManager:show(InfoMessage:new{
                        text = T(_('Send2Ebook lets you send articles found on PC/Android phone to your Ebook reader (using ftp server).\n\nMore details: https://github.com/mwoz123/send2ebook\n\nDownloads to local folder: %1'), download_dir_path)
                    })
                end,
            },
        },
    }
end

function Send2Ebook:lazyInitialization()
   if not initialized then
        logger.dbg("Send2Ebook: obtaining download folder")
        send2ebook_settings = LuaSettings:open(("%s/%s"):format(DataStorage:getSettingsDir(), send2ebook_config_file))
        if send2ebook_settings:has(config_key_custom_dl_dir) then
            download_dir_path = send2ebook_settings:readSetting(config_key_custom_dl_dir)
        else
            download_dir_path = ("%s/%s/"):format(DataStorage:getFullDataDir(), default_download_dir_name)
        end

        if not lfs.attributes(download_dir_path, "mode") then
            logger.dbg("Send2Ebook: Creating initial directory")
            lfs.mkdir(download_dir_path)
        end
    end
end

function Send2Ebook:process()
    local info = InfoMessage:new{ text = _("Connecting…") }
    UIManager:show(info)
    logger.dbg("Send2Ebook: force repaint due to upcoming blocking calls")
    UIManager:forceRePaint()
    UIManager:close(info)

    local count = 1
    local ftp_config = send2ebook_settings:readSetting("ftp_config") or {address="Please setup ftp in settings", username="", password="", folder=""}

    local connection_url = FtpApi:generateUrl(ftp_config.address, ftp_config.username, ftp_config.password)

    local ftp_files_table = FtpApi:listFolder(connection_url .. ftp_config.folder, ftp_config.folder) --args looks strange but otherwise resonse with invalid paths

    if not ftp_files_table then
      info = InfoMessage:new{ text = T(_("Could not get file list for server: %1, user: %2, folder: %3"), ftp_config.address, ftp_config.username, ftp_config.folder) }
    else
      local total_entries = table.getn(ftp_files_table)
      logger.dbg("Send2Ebook: total_entries ", total_entries)
      if total_entries > 1 then total_entries = total_entries -2 end --remove result "../" (upper folder) and "./" (current folder)
      for idx, ftp_file in ipairs(ftp_files_table) do
          logger.dbg("Send2Ebook: processing ftp_file:", ftp_file)
          if ftp_file["type"] == "file" then

              info = InfoMessage:new{ text = T(_("Processing %1/%2"), count, total_entries) }
              UIManager:show(info)
              UIManager:forceRePaint()
              UIManager:close(info)

              local remote_file_path = ftp_file["url"]
              logger.dbg("Send2Ebook: remote_file_path", remote_file_path)
              local local_file_path = download_dir_path .. ftp_file["text"]
              count = count + Send2Ebook:downloadFileAndRemove(connection_url, remote_file_path, local_file_path)
              end
          info = InfoMessage:new{ text = T(_("Processing finished. Success: %1, failed: %2"), count -1, total_entries +1 - count) }
          end
    end
    UIManager:show(info)
    Send2Ebook:afterWifiAction()
end

function Send2Ebook:removeReadActicles()
    logger.dbg("Send2Ebook: Removing read articles from :", download_dir_path)
    for entry in lfs.dir(download_dir_path) do
        if entry ~= "." and entry ~= ".." then
            local entry_path = download_dir_path .. entry
            if DocSettings:hasSidecarFile(entry_path) then
               local entry_mode = lfs.attributes(entry_path, "mode")
               if entry_mode == "file" then
                   os.remove(entry_path)
                   local sdr_dir = DocSettings:getSidecarDir(entry_path)
                   logger.dbg("Send2Ebook: sdr dir to be removed:", sdr_dir)
                   FFIUtil.purgeDir(sdr_dir)
               end
            end
        end
    end
    UIManager:show(InfoMessage:new{
       text = _("All read articles removed.")
    })
end

function Send2Ebook:setCustomDownloadDirectory()
    UIManager:show(InfoMessage:new{
       text = _("To select a folder press down and hold it for 1 second.")
    })
    require("ui/downloadmgr"):new{
       title = _("Choose download directory"),
       onConfirm = function(path)
           logger.dbg("Send2Ebook: set download directory to: ", path)
           send2ebook_settings:saveSetting(config_key_custom_dl_dir, ("%s/"):format(path))
           send2ebook_settings:flush()

           initialized = false
           self:lazyInitialization()
       end,
    }:chooseDir()
end

function Send2Ebook:editFtpConnection()
    local item = send2ebook_settings:readSetting("ftp_config") or {text="ignore this field, it's not used here;) fill rest", address="ftp://", username="",password="" , folder="/"}
    local callbackEdit = function(updated_config, fields)
        local data = {text=fields[1], address=fields[2], username=fields[3],password=fields[4] , folder=fields[5]}
        send2ebook_settings:saveSetting("ftp_config", data)
        send2ebook_settings:flush()
        initialized = false
        Send2Ebook:lazyInitialization()
    end
    Ftp:config(item, callbackEdit)
end

function Send2Ebook:onCloseDocument()
    local document_full_path = self.ui.document.file
    if  document_full_path and download_dir_path and download_dir_path == string.sub(document_full_path, 1, string.len(download_dir_path)) then
        logger.dbg("Send2Ebook: document_full_path:", document_full_path)
        logger.dbg("Send2Ebook: download_dir_path:", download_dir_path)
        logger.dbg("Send2Ebook: removing Send2Ebook file from history.")
        ReadHistory:removeItemByPath(document_full_path)
    end
end

return Send2Ebook
