#include <algorithm>
#include <cmath>

#include "IconsFontAwesome6.h"
#include "layout.h"
#include "localization.h"
#include "rd_log.h"
#include "render.h"

namespace crossdesk {

namespace {
int CountDigits(int number) {
  if (number == 0) return 1;
  return (int)std::floor(std::log10(std::abs(number))) + 1;
}

int BitrateDisplay(int bitrate) {
  int num_of_digits = CountDigits(bitrate);
  if (num_of_digits <= 3) {
    ImGui::Text("%d bps", bitrate);
  } else if (num_of_digits > 3 && num_of_digits <= 6) {
    ImGui::Text("%d kbps", bitrate / 1000);
  } else {
    ImGui::Text("%.1f mbps", bitrate / 1000000.0f);
  }
  return 0;
}
}  // namespace

int Render::FileTransferWindow(
    std::shared_ptr<SubStreamWindowProperties>& props) {
  FileTransferState* state = props ? &props->file_transfer_ : &file_transfer_;

  // Only show window if there are files in transfer list or currently
  // transferring
  std::vector<SubStreamWindowProperties::FileTransferInfo> file_list;
  {
    std::lock_guard<std::mutex> lock(state->file_transfer_list_mutex_);
    file_list = state->file_transfer_list_;
  }

  // Sort file list: Sending first, then Completed, then Queued, then Failed
  std::sort(
      file_list.begin(), file_list.end(),
      [](const SubStreamWindowProperties::FileTransferInfo& a,
         const SubStreamWindowProperties::FileTransferInfo& b) {
        // Priority: Sending > Completed > Queued > Failed
        auto get_priority =
            [](SubStreamWindowProperties::FileTransferStatus status) {
              switch (status) {
                case SubStreamWindowProperties::FileTransferStatus::Sending:
                  return 0;
                case SubStreamWindowProperties::FileTransferStatus::Completed:
                  return 1;
                case SubStreamWindowProperties::FileTransferStatus::Queued:
                  return 2;
                case SubStreamWindowProperties::FileTransferStatus::Failed:
                  return 3;
              }
              return 3;
            };
        return get_priority(a.status) < get_priority(b.status);
      });

  // Only show window if file_transfer_window_visible_ is true
  // Window can be closed by user even during transfer
  // It will be reopened automatically when:
  // 1. A file transfer completes (in render_callback.cpp)
  // 2. A new file starts sending from queue (in render.cpp)
  if (!state->file_transfer_window_visible_) {
    return 0;
  }

  ImGuiIO& io = ImGui::GetIO();

  // Position window at bottom-left of stream window
  // Adjust window size based on number of files
  float file_transfer_window_width = main_window_width_ * 0.6f;
  float file_transfer_window_height =
      main_window_height_ * 0.3f;  // Dynamic height
  float pos_x = file_transfer_window_width * 0.05f;
  float pos_y = stream_window_height_ - file_transfer_window_height -
                file_transfer_window_width * 0.05;
  float same_line_width = file_transfer_window_width * 0.1f;

  ImGui::SetNextWindowPos(ImVec2(pos_x, pos_y), ImGuiCond_Always);
  ImGui::SetNextWindowSize(
      ImVec2(file_transfer_window_width, file_transfer_window_height),
      ImGuiCond_Always);

  // Set Chinese font for proper display
  if (stream_windows_system_chinese_font_) {
    ImGui::PushFont(stream_windows_system_chinese_font_);
  }

  ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f);
  ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 1.0f);
  ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 0.9f));
  ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
  ImGui::PushStyleColor(ImGuiCol_TitleBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
  ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));

  ImGui::SetWindowFontScale(0.5f);
  bool window_opened = true;
  if (ImGui::Begin(
          localization::file_transfer_progress[localization_language_index_]
              .c_str(),
          &window_opened,
          ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
              ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings |
              ImGuiWindowFlags_NoScrollbar)) {
    ImGui::SetWindowFontScale(1.0f);
    ImGui::SetWindowFontScale(0.5f);
    ImGui::PopStyleColor(4);
    ImGui::PopStyleVar(2);

    // Close button handling
    if (!window_opened) {
      state->file_transfer_window_visible_ = false;
      ImGui::End();
      return 0;
    }

    // Display file list
    if (file_list.empty()) {
      ImGui::Text("No files in transfer queue");
    } else {
      // Use a scrollable child window for the file list
      ImGui::SetWindowFontScale(0.5f);
      ImGui::BeginChild(
          "FileList", ImVec2(0, file_transfer_window_height * 0.75f),
          ImGuiChildFlags_Border, ImGuiWindowFlags_HorizontalScrollbar);
      ImGui::SetWindowFontScale(1.0f);
      ImGui::SetWindowFontScale(0.5f);

      for (size_t i = 0; i < file_list.size(); ++i) {
        const auto& info = file_list[i];
        ImGui::PushID(static_cast<int>(i));

        // Status icon and file name
        const char* status_icon = "";
        ImVec4 status_color(0.5f, 0.5f, 0.5f, 1.0f);
        const char* status_text = "";

        switch (info.status) {
          case SubStreamWindowProperties::FileTransferStatus::Queued:
            status_icon = ICON_FA_CLOCK;
            status_color =
                ImVec4(0.5f, 0.6f, 0.7f, 1.0f);  // Common blue-gray for queued
            status_text =
                localization::queued[localization_language_index_].c_str();
            break;
          case SubStreamWindowProperties::FileTransferStatus::Sending:
            status_icon = ICON_FA_ARROW_UP;
            status_color = ImVec4(0.2f, 0.6f, 1.0f, 1.0f);
            status_text =
                localization::sending[localization_language_index_].c_str();
            break;
          case SubStreamWindowProperties::FileTransferStatus::Completed:
            status_icon = ICON_FA_CHECK;
            status_color = ImVec4(0.0f, 0.8f, 0.0f, 1.0f);
            status_text =
                localization::completed[localization_language_index_].c_str();
            break;
          case SubStreamWindowProperties::FileTransferStatus::Failed:
            status_icon = ICON_FA_XMARK;
            status_color = ImVec4(1.0f, 0.2f, 0.2f, 1.0f);
            status_text =
                localization::failed[localization_language_index_].c_str();
            break;
        }

        ImGui::TextColored(status_color, "%s", status_icon);
        ImGui::SameLine();
        ImGui::Text("%s", info.file_name.c_str());
        ImGui::SameLine();
        ImGui::TextColored(status_color, "%s", status_text);

        // Progress bar for sending files
        if (info.status ==
                SubStreamWindowProperties::FileTransferStatus::Sending &&
            info.file_size > 0) {
          float progress = static_cast<float>(info.sent_bytes) /
                           static_cast<float>(info.file_size);
          progress = (std::max)(0.0f, (std::min)(1.0f, progress));

          float text_height = ImGui::GetTextLineHeight();
          ImGui::ProgressBar(
              progress, ImVec2(file_transfer_window_width * 0.5f, text_height),
              "");
          ImGui::SameLine();

          ImGui::Text("%.1f%%", progress * 100.0f);
          ImGui::SameLine();

          float speed_x_pos = file_transfer_window_width * 0.65f;
          ImGui::SetCursorPosX(speed_x_pos);
          BitrateDisplay(static_cast<int>(info.rate_bps));
        } else if (info.status ==
                   SubStreamWindowProperties::FileTransferStatus::Completed) {
          // Show completed size
          char size_str[64];
          if (info.file_size < 1024) {
            snprintf(size_str, sizeof(size_str), "%llu B",
                     (unsigned long long)info.file_size);
          } else if (info.file_size < 1024 * 1024) {
            snprintf(size_str, sizeof(size_str), "%.2f KB",
                     info.file_size / 1024.0f);
          } else {
            snprintf(size_str, sizeof(size_str), "%.2f MB",
                     info.file_size / (1024.0f * 1024.0f));
          }
          ImGui::Text("Size: %s", size_str);
        }

        ImGui::PopID();
        ImGui::Spacing();
      }

      ImGui::SetWindowFontScale(1.0f);
      ImGui::SetWindowFontScale(0.5f);
      ImGui::EndChild();
      ImGui::SetWindowFontScale(1.0f);
    }
    ImGui::SetWindowFontScale(1.0f);
    ImGui::SetWindowFontScale(0.5f);
    ImGui::End();
    ImGui::SetWindowFontScale(1.0f);

    // Pop Chinese font if it was pushed
    if (stream_windows_system_chinese_font_) {
      ImGui::PopFont();
    }
  } else {
    ImGui::PopStyleColor(4);
    ImGui::PopStyleVar(2);
  }
  ImGui::SetWindowFontScale(1.0f);

  return 0;
}

}  // namespace crossdesk
