<template>
  <div>
    <v-toolbar dark>
      <v-spacer />
      <v-toolbar-title>무료 추천 시리즈</v-toolbar-title>
      <v-spacer />
    </v-toolbar>

    <br>

    <v-dialog
      v-model="show_write_dialog"
      max-width="1000px"
      persistent
    >
      <template v-slot:activator="{ on, attrs }">
        <v-container>
          <v-row>
            <v-col cols="9" />
            <v-spacer />
            <v-col>
              <v-btn
                block
                color="#3BB9F1"
                dark
                depressed
                v-bind="attrs"
                v-on="on"
              >
                무료 추천 시리즈 등록
              </v-btn>
            </v-col>
          </v-row>
          <draggable
            v-model="recommend_series_list"
            class="row"
            @end="onDropCallback(recommend_series_list)"
          >
            <v-col
              v-for="(item, i) in recommend_series_list"
              :key="i"
              cols="3"
            >
              <v-card>
                <v-card-title>
                  <v-spacer />
                  <v-img :src="item.imageUrl" />
                  <v-spacer />
                </v-card-title>
                <v-card-actions>
                  <v-spacer />
                  <v-btn
                    text
                    @click="showModifyRecommendSeriesDialog(item)"
                  >
                    수정
                  </v-btn>
                  <v-btn
                    text
                    @click="deleteConfirm(item)"
                  >
                    삭제
                  </v-btn>
                  <v-spacer />
                </v-card-actions>
              </v-card>
            </v-col>
          </draggable>
        </v-container>
      </template>

      <v-card>
        <v-card-title v-if="is_modify === true">
          추천 시리즈 수정
        </v-card-title>
        <v-card-title v-else>
          추천 시리즈 등록
        </v-card-title>

        <v-card-text>
          <v-row align="center">
            <v-col cols="4">
              시리즈
            </v-col>
            <v-col cols="8">
              <v-combobox
                v-model="recommend_series.series_title"
                :items="series"
                :loading="is_loading"
                :search-input.sync="search_query_series"
                label="시리즈를 검색하세요"
                item-text="name"
                item-value="value"
                no-data-text="No results found"
                hide-selected
                clearable
                @change="onSelectSeries"
                @update:search-input="onSearchSeriesUpdate"
              />
            </v-col>
          </v-row>
        </v-card-text>

        <div class="image-select">
          <label for="image">
            추천 시리즈 이미지 등록
          </label>
          <v-file-input
            id="image"
            v-model="recommend_series.image"
            @change="imageAdd"
          />
        </div>
        <img
          v-if="recommend_series.image_url"
          :src="recommend_series.image_url"
          alt=""
          class="image-preview"
        >
        <v-card-actions v-show="!is_loading">
          <v-spacer />
          <v-btn
            color="blue darken-1"
            text
            @click="cancel"
          >
            취소
          </v-btn>
          <v-btn
            v-if="is_modify === true"
            color="blue darken-1"
            text
            @click="modify"
          >
            수정
          </v-btn>
          <v-btn
            v-else
            color="blue darken-1"
            text
            @click="submit"
          >
            등록
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-dialog
      v-model="show_delete_confirm_dialog"
      max-width="400px"
      persistent
    >
      <v-card>
        <v-card-text />
        <v-card-text>
          삭제하시겠습니까?
        </v-card-text>
        <v-card-actions v-show="!is_loading">
          <v-spacer />
          <v-btn
            color="blue darken-1"
            text
            @click="cancel"
          >
            취소
          </v-btn>
          <v-btn
            color="blue darken-1"
            text
            @click="deleteRecommendSeries"
          >
            확인
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<script>
import Draggable from "vuedraggable";
import debounce from "lodash/debounce";

import * as api from "@/api/audio_content_series_recommend"
import * as seriesApi from "@/api/audio_content_series";

export default {
  name: "ContentSeriesRecommendFree",
  components: {Draggable},

  data() {
    return {
      is_selecting: false,
      is_loading: false,
      is_modify: false,
      show_write_dialog: false,
      show_delete_confirm_dialog: false,
      selected_recommend_series: {},
      recommend_series: {},
      recommend_series_list: [],
      series: [],
      search_query_series: '',
    }
  },

  watch: {
    search_query_series() {
      if (!this.is_selecting) {
        this.debouncedSearchSeries();
      }
    }
  },

  async created() {
    await this.getRecommendSeriesList();
  },

  mounted() {
    this.debouncedSearchSeries = debounce(this.searchSeries, 500);
  },

  methods: {
    imageAdd(payload) {
      const file = payload;
      if (file) {
        this.recommend_series.image_url = URL.createObjectURL(file)
        URL.revokeObjectURL(file)
      } else {
        this.recommend_series.image_url = null
      }
    },

    cancel() {
      this.is_modify = false
      this.is_selecting = false
      this.show_write_dialog = false
      this.show_delete_confirm_dialog = false
      this.recommend_series = {}
      this.selected_recommend_series = {}
      this.search_query_series = ''
      this.series = []
    },

    notifyError(message) {
      this.$dialog.notify.error(message)
    },

    notifySuccess(message) {
      this.$dialog.notify.success(message)
    },

    showModifyRecommendSeriesDialog(recommendSeries) {
      this.is_modify = true
      this.selected_recommend_series = recommendSeries

      this.is_selecting = true; // 선택 중 플래그 활성화

      this.recommend_series.id = recommendSeries.id
      this.recommend_series.image_url = recommendSeries.imageUrl
      this.recommend_series.series_id = recommendSeries.seriesId
      this.recommend_series.series_title = recommendSeries.seriesTitle

      setTimeout(() => {
        this.is_selecting = false; // 선택 상태 해제
      }, 1000);

      this.show_write_dialog = true
    },

    deleteConfirm(recommendSeries) {
      this.selected_recommend_series = recommendSeries
      this.show_delete_confirm_dialog = true
    },

    onSelectSeries(value) {
      this.recommend_series.series_id = value.value
      this.is_selecting = true; // 선택 중 플래그 활성화
      setTimeout(() => {
        this.is_selecting = false; // 선택 상태 해제
      }, 0);
    },

    onSearchSeriesUpdate(value) {
      if (!this.is_selecting) {
        this.search_query_series = value
      }
    },

    validate() {
      if (this.recommend_series.series_id === null || this.recommend_series.series_id === undefined) {
        this.notifyError("시리즈를 선택하세요")
        return false;
      }

      return true;
    },

    async getRecommendSeriesList() {
      this.is_loading = true
      try {
        const res = await api.getRecommendSeriesList(true)
        if (res.status === 200 && res.data.success === true) {
          this.recommend_series_list = res.data.data
        } else {
          this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
        }
      } catch (e) {
        this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
        this.is_loading = false
      } finally {
        this.is_loading = false
      }
    },

    async submit() {
      if (!this.validate()) return;
      if (this.is_loading === true) return;

      this.is_loading = true

      try {
        const formData = new FormData()
        formData.append("image", this.recommend_series.image)

        let request = {
          seriesId: this.recommend_series.series_id,
          isFree: true
        }

        formData.append("request", JSON.stringify(request))

        const res = await api.saveRecommendSeries(formData)
        if (res.status === 200 && res.data.success === true) {
          this.cancel()
          this.notifySuccess('등록되었습니다.')

          this.recommend_series_list = []
          await this.getRecommendSeriesList()
        } else {
          this.notifyError(res.data.message);
        }
      } catch (e) {
        this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
      } finally {
        this.is_loading = false
      }
    },

    async modify() {
      if (this.is_loading) return;

      this.is_loading = true
      try {
        const formData = new FormData()
        let request = {id: this.recommend_series.id}

        if (this.recommend_series.image !== null) {
          formData.append("image", this.recommend_series.image)
        }

        if (
          this.selected_recommend_series.series_id !== this.recommend_series.series_id &&
          this.recommend_series.series_id !== null &&
          this.recommend_series.series_id !== undefined
        ) {
          request.seriesId = this.recommend_series.series_id
        }

        formData.append("request", JSON.stringify(request))

        const res = await api.modifyRecommendSeries(formData)
        if (res.status === 200 && res.data.success === true) {
          this.cancel()
          this.notifySuccess('수정되었습니다.')

          this.recommend_series_list = []
          await this.getRecommendSeriesList()
        } else {
          this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
        }
      } catch (e) {
        this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
      } finally {
        this.is_loading = false
      }
    },

    async deleteRecommendSeries() {
      if (this.is_loading) return;
      this.is_loading = true

      try {
        const formData = new FormData()
        formData.append("request", JSON.stringify({id: this.selected_recommend_series.id, isActive: false}))
        const res = await api.modifyRecommendSeries(formData)
        if (res.status === 200 && res.data.success === true) {
          this.show_delete_confirm_dialog = false
          this.cancel()
          this.notifySuccess('삭제되었습니다.')

          this.recommend_series_list = []
          await this.getRecommendSeriesList()
        } else {
          this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
        }
      } catch (e) {
        this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
      } finally {
        this.is_loading = false
      }
    },

    async onDropCallback(items) {
      const ids = items.map((item) => {
        return item.id
      })

      const res = await api.updateRecommendSeriesOrders(ids)
      if (res.status === 200 && res.data.success === true) {
        this.notifySuccess(res.data.message || '수정되었습니다.')
      }
    },

    async searchSeries() {
      if (this.search_query_series === null || this.search_query_series.length < 2) {
        this.series = [];
        return;
      }

      this.is_loading = true;

      try {
        const res = await seriesApi.searchSeriesList(this.search_query_series);

        if (res.status === 200 && res.data.success === true) {
          this.series = res.data.data.map((item) => {
            return {name: item.title, value: item.id}
          })
        } else {
          this.series = []
        }
      } catch (e) {
        this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
        this.is_loading = false
      } finally {
        this.is_loading = false
      }
    },
  }
}
</script>

<style scoped>
.image-select label {
  display: inline-block;
  padding: 10px 20px;
  background-color: #232d4a;
  color: #fff;
  vertical-align: middle;
  font-size: 15px;
  cursor: pointer;
  border-radius: 5px;
}

.v-file-input {
  position: absolute;
  width: 0;
  height: 0;
  padding: 0;
  overflow: hidden;
  border: 0;
}

.image-preview {
  max-width: 100%;
  width: 250px;
  object-fit: cover;
  margin-top: 10px;
}
</style>
