require_relative "../global_context"

class BlogContext < GlobalContext

  include ContentDataSetup
  include FormTester

  # FORM DATA -----

  def create_blog_category_data!
    @blog_category_data = {
      valid: {
        content_category_1: {
          "category1 - titleText": "This is the new title text for content category 1",
          "category1 - description": "This is the meta description for content category 1",
          "category1 - header": "This is the new header for content category 1",
          "category1 - contentDownload1Id": @content_download_2.name # Capybara selects on text, not value
        }
      },
      invalid: {
        content_category_1: {
          "category1 - description": "",
          "category1 - header": "",
          "category1 - contentDownload1WorkflowId": "",
        }
      },
      errors: {
        content_category_1: [
          "Category 1 Description can't be blank",
          "Category 1 Header can't be blank",
          "Category 1 Workflow ID 1 is not a number"
        ]
      }
    }
  end

  def create_blog_settings_data!
    content_download_2_name = @content_download_2.name
    @blog_settings_data = {
      valid: {
        homepage: {
          "homepage - header": "This is the new homepage header",
          "homepage - subheader": "This is the new homepage subheader",
          "homepage - contentDownload1": content_download_2_name
        },
        resources: {
          "resources - header": "This is the new resources header",
          "resources - subheader": "This is the new resources subheader",
          "resources - featuredContentDownload": content_download_2_name
        }
      },
      invalid: {
        homepage: {
          "homepage - header": "",
          "homepage - contentDownload1WorkflowId": "a"
        },
        resources: {
          "resources - subheader": "",
          "resources - featuredContentDownloadEventName": "",
          "resources - featuredContentDownloadWorkflowId": "this is not a number"
        }
      },
      errors: {
        homepage: [
          "Homepage Header is mandatory",
          "Homepage Workflow ID 1 is not a number"
        ],
        resources: [
          "Resources Subheader is mandatory",
          "Resources Featured CU Event Name is mandatory",
          "Resources Featured CU Workflow ID is not a number"
        ]
      }
    }
  end

  def initialize
    create_permissions!
    @blog_post_data = {
      create: {
        title: "Test Blog Post",
        title_text: "Test Blog Post Title Text",
        description: "Test Blog Post Meta Description"
      },
      update: {
        standard: {
          title: "This is the new title",
          active: "Yes"
        },
        content: {
          text_editor: "This is some blog content",
        },
      }
    }
  end

  # BLOG SETTINGS -----

  def fill_in_blog_settings(validity)
    blog_settings_data = @blog_settings_data[validity]
    blog_settings_data.each do |tab_name, field_data|
      click_tab(tab_name)
      fill_in_form(field_data, -> (camelcase_name) { "##{tab_name}-#{camelcase_name}" })
    end
  end

  def expect_valid_blog_settings_content
    @blog_settings_data[:valid].keys.each do |tab_name|
      url = "/blog/category" + (tab_name == :homepage ? "" : "#{tab_name}")
      visit_page(url)
      expect_form_values(@blog_settings_data[:valid][tab_name])
    end
  end

  def expect_invalid_blog_settings_content
    @blog_settings_data[:errors].keys.each do |tab_name|
      click_tab(tab_name)
      expect_form_errors(@blog_settings_data[:errors][tab_name])
    end
  end

  # CATEGORY SETTINGS -----

  def fill_in_category_settings(validity)
    category_data = @blog_category_data[validity]
    category_data.keys.each_with_index do |tab_name, i|
      click_tab(tab_name)
      field_data = category_data[tab_name]
      fill_in_form(field_data, -> (camelcase_name) { "#category#{i + 1}-#{camelcase_name}" })
    end
  end

  def expect_valid_category_content
    @blog_category_data[:valid].keys.each do |tab_name|
      url = "/blog/category/" + (tab_name.to_s.split('_').map(&:downcase).join('-'))
      visit_page(url)
      valid_data = @blog_category_data[:valid][tab_name]
      valid_data.each do |field_name, field_value|
        case field_name.to_s
        when "category1 - titleText"
          expect page.title == field_value
        when "category1 - description"
          description = page.find('meta[name="description"]', visible: false)
          expect(description[:content]).to eq(field_value)
        else
          expect_content_on_page(field_value)
        end
      end
    end
  end

  def expect_invalid_category_content
    @blog_category_data[:errors].keys.each do |tab_name|
      click_tab(tab_name)
      expect_form_errors(@blog_category_data[:errors][tab_name])
    end
  end

  # BLOG POST CREATE -----

  def fill_in_form_element(elementId, field_value)
    element = find(elementId, visible: false)
    case element.tag_name
      when "input"
        element.set(field_value, clear: :backspace)
      when "select"
        change_nice_select_option(field_value, element)
    end
  end

  def fill_in_new_blog_post_form
    new_blog_post_data = @blog_post_data[:create]
    find('input[data-field="title"]').set(new_blog_post_data[:title], clear: :backspace)
    find('input[data-field="titleText"]').set(new_blog_post_data[:title_text], clear: :backspace)
    date = (DateTime.now + 1).strftime("%-m/%-d/%Y")
    new_blog_post_data[:date] = date
    find('input[data-field="date"]').set(date, clear: :backspace)
  end

  def expect_blog_post_existence
    blog_post = BlogPost.find_by(title: @blog_post_data[:create][:title])
    expect(blog_post).to be_truthy
    expect(blog_post.title_text).to eq(@blog_post_data[:create][:title_text])
    expect(blog_post.date.strftime("%-m/%-d/%Y")).to eq(@blog_post_data[:create][:date])
  end

  # BLOG POST UPDATE -----

  def visit_blog_details_page
    @blog_post = BlogPost.create!(@blog_post_data[:create].merge({ author: @current_user, url: "/test-blog-post", canonical_url: "https://teachable.com/blog/test-blog-post" }))
    wait_until { BlogPost.count > 0 }
    visit_page("/admin/blog_posts/#{@blog_post.id}")
  end

  def update_blog_post_content!
    update_blog_post_data = @blog_post_data[:update]
    data = update_blog_post_data[:standard]
    new_fill_in_form(data)
    click_a_tag("Save")
    wait_for_ajax
    click_tab("content")
    text_editor = find(".notranslate.public-DraftEditor-content", visible: false)
    text_editor.click
    text_editor.send_keys @blog_post_data[:update][:content][:text_editor]
    click_a_tag("Save")
  end

  def expect_public_blog_post_updates
    visit_page("/blog" + @blog_post.url)
    expect_form_values(@blog_post_data[:update][:standard].except(:active))
  end

  def select_first_category
    first_category = ContentCategory.general[0]
    checkbox = find("label.checkbox", text: first_category.name.titleize)
    checkbox.set(true)
    fill_in_form_element("select[data-field=\"active\"]", "Yes") # ensure the post is active, in case the tests are being run out of order
  end

  def expect_public_category_page_updates
    category = ContentCategory.general[0]
    visit_page(category.url)
    expect_content_on_page(@blog_post.title)
  end

  # BlOG POST DELETE -----

  def expect_deleted_post
    deleted_post = BlogPost.where(id: @blog_post.id)[0]
    expect(deleted_post).to be_falsey
  end

  # CONTENT UPGRADES & NEWSLETTER -----

  def sign_up_for_content_download(content_download_index, validity)
    selector = content_download_index == 1 ? ".content-download-hero-form.top" : "content-download-hero-form.bottom"

    fill_in_email(selector + " input.email-input", validity)
    find(selector + " a.blog-featured-cta-button").click
  end

  def expect_content_download_landing_page(content_download_index)
    content_download = content_download_index == 1 ? @content_download_1 : @content_download_2
    switch_to_recently_opened_tab
    expect(current_path).to eq(content_download.landing_page_url)
  end

  def expect_content_download_thank_you_page(content_download_index)
    content_download = ContentDownload.find(content_download_index)
    correct_url = "/get/#{content_download.landing_page_slug}/thank-you"

    expect(page.has_content?(content_download.name)).to be_truthy
    expect(page.has_content?("Check your email inbox to receive your download.")).to be_truthy
    expect(current_path).to eq(correct_url)
  end

  def expect_email_input_error(error_type)
    error_type = error_type.to_sym
    error_selectors = {
      "top hero": ".content-download-hero-form.top div.email-input-container.error",
      "bottom hero": ".content-download-hero-form.bottom div.email-input-container.error",
      newsletter: ".blog-signup-modal div.email-input-container.error",
    }

    expect page.has_css?(error_selectors[error_type])
  end

  # HELPERS -----

  def fill_in_email(selector, validity)
    email = validity ? "hi@hi.hi" : "invalid email"
    find(selector).set(email)
  end

  def visit_page(url)
    params = @current_user ? "?as=#{@current_user.name}" : ""
    visit url + params
  end

  def visit_blog_page(page_name)
    page_name = page_name.to_sym
    categories = ContentCategory.general

    blog_page_urls = {
      home: "/blog",
      resources: "/blog/resources",
      category1: categories[0].url,
      category2: categories[1].url,
      category3: categories[2].url
    }

    visit_page(blog_page_urls[page_name])
  end

  def click_tab(tab_name)
    text = tab_name.to_s.titleize
    find('div.tab', text: text).click
  end

  private

  def create_user!(name)
    user = User.create!(
      name: name,
      email: "#{name.downcase}@teachable.com",
      password: "123456",
      team_id: 1,
      permission_id: 2,
    )

    profile_pic = Upload.create!(
      category: "user",
      upload_type: "image",
      uploaded_by: user.id,
      url: "https://cdn.filepicker.io/api/file/g65lEfxrTaqAgouYOGym",
    )

    user.update(image_id: profile_pic.id)
    user
  end

  def create_permissions!
    permissions = {
      'No access' => 0,
      'User' => 1,
      'Administrator' => 2,
      'Super administrator' => 3
    }
    permissions.each { |name, level| Permission.create!(name: name, level: level) }
  end

end
