<template>
  <wrapper
    margin
    padding
    background
  >
    <grid-table
      ref="table"
      :schema="schema"
    >
      <grid-table-item v-slot="item">
        <div class="l-flex--col c-program">
          <div
            class="c-program__body u-pointer"
            :style="item.style"
            @click="onClickProgram(item)"
          >
            <i
              v-if="item.status === 1"
              class="c-program__status el-icon-lock u-color--warning"
            />
            <i
              v-if="item.status === 2"
              class="c-program__status el-icon-circle-check u-color--success"
            />
            <span class="c-program__rate">
              {{ item.resolutionRatio }}
            </span>
            <div class="c-program__footer">
              <span class="c-program__time u-ellipsis">{{ item.createTime }}</span>
              <el-tooltip
                v-if="item.status === 0"
                content="提交"
                :hide-after="2000"
              >
                <i
                  class="o-icon--active el-icon-upload2 u-pointer"
                  @click.stop="onSubmit(item)"
                />
              </el-tooltip>
              <el-tooltip
                v-if="item.status === 2"
                content="复制"
                :hide-after="2000"
              >
                <svg-icon
                  class="o-icon--active u-pointer"
                  icon-class="copy"
                  @click.stop="onCopy(item)"
                />
              </el-tooltip>
              <permission
                :skip="item.status === 0"
                :access="Access.DELETE_FORCE"
              >
                <el-tooltip
                  content="删除"
                  :hide-after="2000"
                >
                  <i
                    class="o-icon--active el-icon-delete u-pointer"
                    @click.stop="onDel(item)"
                  />
                </el-tooltip>
              </permission>
            </div>
          </div>
          <edit-input
            v-model.trim="item.name"
            class="c-program__name"
            :disabled="item.status !== 0"
            align="left"
            @edit="onEdit(item)"
          />
        </div>
      </grid-table-item>
    </grid-table>
    <confirm-dialog
      ref="addDialog"
      title="新增节目"
      @confirm="onConfirmAdd"
    >
      <div class="c-grid-form u-align-self--center">
        <span class="c-grid-form__label required">名称：</span>
        <el-input
          v-model.trim="program.name"
          placeholder="请填写节目名称"
          maxlength="50"
          show-word-limit
        />
        <span class="c-grid-form__label required">分辨率：</span>
        <schema-select
          v-model="program.resolutionRatio"
          placeholder="请选择分辨率"
          :schema="resolutionRatioSelectSchema"
        />
      </div>
    </confirm-dialog>
    <confirm-dialog
      ref="copyDialog"
      title="复制节目"
      @confirm="onConfirmCopy"
    >
      <div class="c-grid-form u-align-self--center">
        <span class="c-grid-form__label required">名称：</span>
        <el-input
          v-model.trim="copyProgram.name"
          placeholder="请填写节目名称"
          maxlength="50"
          show-word-limit
        />
      </div>
    </confirm-dialog>
  </wrapper>
</template>

<script>
import { getAssetUrl } from '@/api/asset'
import { getRatios } from '@/api/device'
import {
  getPrograms,
  addProgram,
  updateProgramName,
  deleteProgram,
  getProgram,
  submitProgram,
  copyProgram
} from '@/api/program'
import { State } from '@/constant'
import { validate } from './core/utils'

export default {
  name: 'BigScreen',
  data () {
    return {
      program: {},
      copyProgram: {
        id: null,
        name: ''
      },
      resolutionRatioSelectSchema: { remote: this.getRatios },
      schema: {
        condition: {
          status: void 0,
          resolutionRatio: void 0,
          name: ''
        },
        list: getPrograms,
        buttons: [
          { type: 'add', on: this.onAdd }
        ],
        filters: [
          { key: 'resolutionRatio', type: 'select', placeholder: '全部分辨率', simple: true, remote: getRatios },
          { key: 'status', type: 'select', placeholder: '全部状态', options: [
            { value: State.READY, label: '待提交' },
            { value: State.SUBMITTED, label: '未审核' },
            { value: State.RESOLVED, label: '已审核' }
          ] },
          { key: 'name', type: 'search', placeholder: '节目名称' }
        ],
        transform: this.transform
      }
    }
  },
  created () {
    window.addEventListener('message', this.onMessage)
  },
  beforeDestroy () {
    window.removeEventListener('message', this.onMessage)
  },
  methods: {
    onMessage (event) {
      if (!this.loading) {
        const id = event.data?.id
        if (id) {
          const program = this.$refs.table.getData().find(program => program.id === id)
          if (program) {
            program.style = this.getStyle(event.data.base64, true)
          }
        }
      }
    },
    getRatios (params) {
      return getRatios(params).then(({ data }) => {
        return {
          data: data.map(({ value, label, devices }) => {
            return {
              value,
              label: `${label} ${devices}`
            }
          })
        }
      })
    },
    transform ({ id, name, status, resolutionRatio, createTime, img }) {
      return {
        id, name, status, resolutionRatio,
        style: this.getStyle(img),
        createTime: createTime?.split(' ')[0],
        originalName: name
      }
    },
    getStyle (img, base64) {
      return img ? {
        backgroundSize: 'contain',
        backgroundImage: `url("${base64 || /^data/.test(img) ? img : getAssetUrl(img)}")`
      } : {}
    },
    onEdit (item) {
      if (!item.name) {
        item.name = item.originalName
        return
      }

      if (item.name === item.originalName) {
        return
      }

      updateProgramName({
        id: item.id,
        name: item.name
      }).then(() => {
        item.originalName = item.name
      }, () => {
        item.name = item.originalName
      })
    },
    onAdd () {
      this.program = {
        name: '',
        resolutionRatio: ''
      }
      this.$refs.addDialog.show()
    },
    onConfirmAdd (done) {
      if (!this.program.name) {
        this.$message({
          type: 'warning',
          message: '名称不能为空'
        })
        return
      }
      if (!this.program.resolutionRatio) {
        this.$message({
          type: 'warning',
          message: '请选择分辨率'
        })
        return
      }
      addProgram(this.program).then(({ data: id }) => {
        done()
        this.$refs.table.resetCondition({ status: State.READY, name: this.program.name })
        this.onDesign(id)
      })
    },
    onDesign (id) {
      window.open(this.$router.resolve({
        name: 'program',
        params: { id }
      }).href, '_blank')
    },
    onView (id) {
      window.open(this.$router.resolve({
        name: 'program',
        params: { id }
      }).href, '_blank')
    },
    onClickProgram (item) {
      const { id, status } = item
      if (status === State.READY) {
        this.onDesign(id)
      } else {
        this.onView(id)
      }
    },
    onSubmit (item) {
      const loading = this.$showLoading()
      getProgram(item.id).then(({ data }) => {
        const { itemJsonStr } = data
        if (!itemJsonStr) {
          this.$message({
            type: 'warning',
            message: `请先编辑节目`
          })
          return
        }
        try {
          const error = validate(JSON.parse(itemJsonStr))
          if (error) {
            this.$message({
              type: 'warning',
              message: error
            })
            return
          }
        } catch (e) {
          this.$message({
            type: 'warning',
            message: `节目数据异常`
          })
          return
        }
        submitProgram(item).then(() => {
          this.$refs.table.resetCondition({ status: State.SUBMITTED })
        })
      }).finally(() => {
        this.$closeLoading(loading)
      })
    },
    onDel (item) {
      deleteProgram(item).then(() => {
        this.$refs.table.decrease(1)
      })
    },
    onCopy ({ id, name }) {
      this.copyProgram = { id, name }
      this.$refs.copyDialog.show()
    },
    onConfirmCopy (done) {
      const { id, name } = this.copyProgram
      copyProgram({ id }, name).then(() => {
        done()
        this.$refs.table.resetCondition({ status: State.READY, name })
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.c-program {
  &__body {
    position: relative;
    padding-top: 60%;
    color: #fff;
    font-size: 16px;
    border-radius: $radius;
    background: rgba(0, 0, 0, 0.8) url("~@/assets/program_bg.png") center center /
      100% 100% no-repeat;
    overflow: hidden;
  }

  &__status {
    position: absolute;
    top: 6px;
    left: 6px;
    font-size: 24px;
  }

  &__rate {
    position: absolute;
    top: 0;
    right: 0;
    padding: 2px 4px;
    font-size: 12px;
    background-color: rgba(0, 0, 0, 0.5);
    border-radius: 0 0 0 4px;
  }

  &__name {
    color: $black;
    font-weight: bold;
  }

  &__footer {
    display: inline-flex;
    align-items: center;
    position: absolute;
    width: 100%;
    bottom: 0;
    padding: 24px 16px 16px;
    background-image: linear-gradient(
      to bottom,
      rgba(#000, 0) 0%,
      rgba(#000, 0.6) 100%
    );

    .o-icon--active {
      margin-left: $spacing;
      font-size: 18px;
    }
  }

  &__time {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 14px;
  }
}
</style>
