require "rails_helper"

RSpec.describe VideoAnalyses::GraphicsElementsController, type: :controller do
  let(:user) { create(:user) }
  let(:project) { create(:project, account: user.primary_account) }
  let(:video) { create(:video, project: project) }

  before :each do
    sign_in(user)
  end

  render_views

  describe "#new" do
    let(:edl_gateway) { double(:edl_gateway) }

    before :each do
      allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
      allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
    end

    it "responds successfully and sets graphics_element, edl_events_data, matched_filename" do
      get :new, params: {
        video_id: video.id,
        graphics_element: {
          text: "asdf",
          time_elapsed: "00:01:00",
          channel: "V",
          timecode_in: "timecode_in",
          timecode_out: "timecode_out",
          duration: "duration",
          source_file_name: "source_file_name",
          clip_name: "clip_name",
          description: "description",
          edl_type: "edl_type",
        },
        matched_file_name: "matched_file_name",
      }, xhr: true

      expect(EdlEventGateway).to have_received(:new).with(
        instance_of(GraphicsFilesForRequest),
        "00:00:00:00",
        "00:00:00:00",
        channel_filter: "V",
      )

      expect(response).to be_successful
      expect(assigns(:graphics_element)).to have_attributes(
        id: nil,
        text: "asdf",
        time_elapsed: "00:01:00",
        clip_name: "clip_name",
        description: "description",
        duration: "duration",
        source_file_name: "source_file_name",
        channel: "V",
        timecode_in: "timecode_in",
        timecode_out: "timecode_out",
        edl_type: "edl_type",
      )
      expect(assigns(:edl_events_data)).to eq({
        edl_events: build_list(:edl_event, 1),
        edl_attributes: {
          channel: "V",
          timecode_in: "timecode_in",
          timecode_out: "timecode_out",
          duration: "duration",
          source_file_name: "source_file_name",
          clip_name: "clip_name",
          description: "description",
        },
        info_message: "An EDL event was found. Data is shown below",
      })
      expect(assigns(:matched_file_name)).to eq "matched_file_name"
    end

    context "when edl_type param is all_tracks" do
      it "uses the all tracks edl" do
        get :new, params: {
          video_id: video.id,
          graphics_element: {
            text: "asdf",
            time_elapsed: "00:01:00",
            channel: "V",
            timecode_in: "timecode_in",
            timecode_out: "timecode_out",
            duration: "duration",
            source_file_name: "source_file_name",
            clip_name: "clip_name",
            description: "description",
            edl_type: "all_tracks",
          },
          matched_file_name: "matched_file_name",
        }, xhr: true

        expect(EdlEventGateway).to have_received(:new).with(
          instance_of(FilesForRequest),
          "00:00:00:00",
          "00:00:00:00",
          channel_filter: "V",
        )
      end
    end
  end

  describe "#create" do
    it "responds successfully and creates graphics_element" do
      expect {
        post :create, params: {
          video_id: video.id,
          graphics_element: {
            graphic_type: "Subtitle",
            text: "asdf",
            time_elapsed: "00:01:00",
            channel: "V",
            timecode_in: "timecode_in",
            timecode_out: "timecode_out",
            duration: "duration",
            source_file_name: "source_file_name",
            clip_name: "clip_name",
            description: "description",
            edl_type: "edl_type",
          },
        }, xhr: true
      }.to change(GraphicsElement, :count).by(1)

      expect(response).to be_successful
    end

    it "sets graphics_element_data, graphics_elements_data" do
      post :create, params: {
        video_id: video.id,
        graphics_element: {
          graphic_type: "Subtitle",
          text: "asdf",
          time_elapsed: "00:01:00",
          channel: "V",
          timecode_in: "timecode_in",
          timecode_out: "timecode_out",
          duration: "duration",
          source_file_name: "source_file_name",
          clip_name: "clip_name",
          description: "description",
          edl_type: "edl_type",
        },
      }, xhr: true

      expect(assigns(:graphics_element_data)).to have_attributes(
        source_file_name: "source_file_name",
        timecode_in: "timecode_in",
        should_toggle_checkmark: true,
        is_valid: true,
      )
      expect(assigns(:graphics_elements_data)).to have_attributes(
        graphics_elements: [GraphicsElement.last]
      )
    end
  end

  describe "#edit" do
    let(:edl_gateway) { double(:edl_gateway) }

    before :each do
      allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
      allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
    end

    it "sets graphics_element, edl_events_data" do
      graphics_element = create(:graphics_element, video: video)

      get :edit, params: { id: graphics_element }, xhr: true

      expect(EdlEventGateway).to have_received(:new).with(
        instance_of(GraphicsFilesForRequest),
        "00:00:05:00",
        "00:00:05:00",
        channel_filter: "V",
      )

      expect(response).to be_successful
      expect(assigns(:graphics_element)).to eq graphics_element
      expect(assigns(:edl_events_data)).to eq({
        edl_events: build_list(:edl_event, 1),
        edl_attributes: {
          channel: "V",
          timecode_in: "timecode_in",
          timecode_out: "timecode_out",
          duration: "duration",
          source_file_name: "source_file_name",
          clip_name: "clip_name",
          description: "description",
        },
        info_message: "An EDL event was found. Data is shown below",
      })
    end

    context "when edl_type param is all_tracks" do
      it "uses the all tracks edl" do
        graphics_element = create(:graphics_element, video: video, edl_type: "all_tracks")

        get :edit, params: { id: graphics_element }, xhr: true

        expect(EdlEventGateway).to have_received(:new).with(
          instance_of(FilesForRequest),
          "00:00:05:00",
          "00:00:05:00",
          channel_filter: "V",
        )
      end
    end
  end

  describe "#update" do
    let(:edl_gateway) { double(:edl_gateway) }

    before :each do
      allow(EdlEventGateway).to receive(:new).and_return(edl_gateway)
      allow(edl_gateway).to receive(:edl_events).and_return(build_list(:edl_event, 1))
    end

    it "sets graphics_element_data, graphics_elements_data" do
      graphics_element = create(:graphics_element, video: video)

      put :update, params: {
        id: graphics_element,
        graphics_element: {
          graphic_type: "Subtitle",
          text: "text",
          time_elapsed: "time_elapsed",
          channel: "V",
          timecode_in: "timecode_in",
          timecode_out: "timecode_out",
          duration: "duration",
          source_file_name: "source_file_name",
          clip_name: "clip_name",
          description: "description",
        }
      }, xhr: true

      expect(response).to be_successful
      expect(assigns(:graphics_element_data)).to have_attributes(
        source_file_name: "source_file_name",
        timecode_in: "timecode_in",
        should_toggle_checkmark: true,
        is_valid: true,
      )
      expect(assigns(:graphics_elements_data).graphics_elements.first).to have_attributes(
        text: "text",
        time_elapsed: "time_elapsed",
        timecode_in: "timecode_in",
        timecode_out: "timecode_out",
        duration: "duration",
        source_file_name: "source_file_name",
        clip_name: "clip_name",
        description: "description",
      )
    end
  end

  describe "#delete" do
    it "deletes given graphics_element" do
      graphics_element = create(:graphics_element)

      expect {
        delete :destroy, params: { id: graphics_element }, xhr: true }.to change { GraphicsElement.count
      }.from(1).to(0)
    end

    it "responds with graphics element data, graphics elements data" do
      graphics_element = create(:graphics_element,
        video: video,
        source_file_name: "source_file_name",
        timecode_in: "timecode_in",
      )

      delete :destroy, params: { id: graphics_element }, xhr: true

      expect(assigns(:graphics_element_data)).to have_attributes(
        source_file_name: "source_file_name",
        timecode_in: "timecode_in",
        should_toggle_checkmark: true,
        is_valid: true,
      )
      expect(assigns(:graphics_elements_data)).to have_attributes(
        graphics_elements: []
      )
    end
  end
end
