<template>
  <a-spin :spinning="state.downloadLoading" tip="下载中...">
    <div class="mediaDetail">
      <Search :mode="state.mode" :fetchList="fetchList" :selectedRowKeys="state.selectedRowKeys"
        :onClickDownload="onClickBatchDownload" :onClickDelete="onClickBatchDelete" :onClickSearch="onClickSearch"
        :onClickReset="onClickReset" />
      <div style="background: #FFFFFF;padding: 20px;">
        <div class="mediaDetail-info">
          <div class="mediaDetail-info-left">
            <div style="color: #7C7C7C;cursor: pointer;" @click="onClickGoBack">
              媒体文件
            </div>
            <div style="margin: 0 10px;">
              /
            </div>
            <div>
              {{ state.dirName }}
            </div>
          </div>
          <div class="mediaDetail-info-right">
            <div class="mediaDetail-info-right-text">
              <div>
                已选/全部：
              </div>
              <div>
                {{ state.selectedRowKeys.length }}/{{ paginationConfig.total }}
              </div>
            </div>
            <a-button style="padding:0 5px;" :type="state.mode === 'table' ? 'primary' : 'default'"
              :ghost="state.mode === 'table'" size="small" @click="state.mode = 'table'">
              <MenuOutlined />
            </a-button>
            <a-button style="padding:0 5px;" :type="state.mode === 'list' ? 'primary' : 'default'"
              :ghost="state.mode === 'list'" size="small" @click="state.mode = 'list'">
              <AppstoreOutlined />
            </a-button>
          </div>
        </div>
        <div class="mediaDetail-table" v-if="state.mode === 'table'">
          <a-table :scroll="{ x: '100%', y: 500 }" :childrenColumnName="null" rowKey="file_id"
            :loading="state.listLoading" :columns="columns" :dataSource="state.list" :rowClassName="rowClassName"
            :pagination="paginationConfig"
            :rowSelection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }">
            <!-- 文件夹名称 -->
            <template #file_name="{ record }">
              <a-tooltip :title="record.file_name">
                <div class="fileName">
                  <div @click="onClickLookFile(record)">
                    <img :src="panoramaSrc" v-if="record.media_type === 3" />
                    <img :src="videoSrc" v-else-if="record.media_type === 4" />
                    <img :src="pictureSrc" v-else />
                  </div>
                  <div>
                    <a-input v-model:value="record.file_name" v-if="state.editableData[record.file_id]" />
                    <div @click="onClickLookFile(record)" v-else>
                      {{ record.file_name }}
                    </div>
                  </div>
                </div>
              </a-tooltip>
            </template>
            <!-- 操作 -->
            <template #action="{ record }">
              <!-- 编辑态操作 -->
              <div v-if="state.editableData[record.file_id]">
                <a-tooltip title="确定">
                  <CheckOutlined style="color: #28d445;margin-right: 10px;" @click="onClickSave(record)" />
                </a-tooltip>
                <a-tooltip title="取消">
                  <CloseOutlined style="color: #e70102;" @click="() => delete state.editableData[record.file_id]" />
                </a-tooltip>
              </div>
              <!-- 非编辑态操作 -->
              <div class="flex-align-center flex-row" style="color: #2d8cf0" v-else>
                <div v-if="[1, 3].includes(record.media_type)">
                  <a-tooltip title="在地图上加载" v-if="!record.element_id">
                    <AimOutlined style="margin-right: 10px;" @click="onClickCreateMapElement(record.file_id)" />
                  </a-tooltip>
                  <a-tooltip title="在地图上取消加载" v-else>
                    <AimOutlined style="color: #e70102;margin-right: 10px;"
                      @click="onClickDeleteMapElement(record.file_id)" />
                  </a-tooltip>
                </div>
                <a-tooltip title="重命名" v-else-if="record.media_type === 4">
                  <EditOutlined style="margin-right: 10px;" @click="onClickRechristen(record)" />
                </a-tooltip>
                <a-tooltip title="删除" v-else-if="record.media_type === 2">
                  <DeleteOutlined style="margin-right: 10px;" @click="onClickDelete(record)" />
                </a-tooltip>
                <a-tooltip title="压缩下载">
                  <DownloadOutlined @click="onClickDownload(record)" />
                </a-tooltip>
              </div>
            </template>
          </a-table>
        </div>
        <div class="mediaDetail-list" v-else>
          <a-list :grid="{ gutter: 16, xs: 1, sm: 2, md: 3, lg: 4, xl: 8, xxl: 12 }" :loading="state.listLoading"
            :dataSource="state.list" :pagination="paginationConfig">
            <template #renderItem="{ item }">
              <a-list-item>
                <a-card hoverable @click="onClickLookFile(item)">
                  <template #cover>
                    <div style="display: flex;justify-content:center;align-items: center;">
                      <img style="width: 70%;margin: 10px;" :src="pictureSrc" />
                    </div>
                  </template>
                  <a-card-meta>
                    <template #description>
                      <div class="mediaDetail-list-name">
                        {{ item.file_name }}
                      </div>
                    </template>
                  </a-card-meta>
                </a-card>
              </a-list-item>
            </template>
          </a-list>
        </div>
      </div>
    </div>
  </a-spin>
  <FileInfo :fileId="state.fileId" :onClose="fileInfoOnClickClose" v-if="state.fileInfoVisible" />
</template>

<script lang="ts" setup>
import { reactive, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { MenuOutlined, AppstoreOutlined, EditOutlined, DeleteOutlined, DownloadOutlined, AimOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons-vue';
import Search from './components/Search.vue';
import FileInfo from './components/FileInfo.vue';
import pictureSrc from '/@/assets/media/picture.svg';
import panoramaSrc from '/@/assets/media/panorama.svg';
import videoSrc from '/@/assets/media/video.svg';
import { apis } from '/@/api/custom';
import router from '/@/router/index';
import { downloadFile } from '/@/utils/common';
import { downloadMediaFile } from '/@/api/media';
import { ELocalStorageKey } from '/@/types';

interface State {
  query: any,
  listLoading: boolean,
  list: any[],
  dirName: string,
  selectedRowKeys: string[],
  editableData: {
    [key: string]: string,
  },
  downloadLoading: boolean,
  mode: 'table' | 'list',
  fileId: string,
  fileInfoVisible: boolean,
};

const state: State = reactive({
  query: undefined,
  listLoading: false,
  list: [],
  dirName: '',
  selectedRowKeys: [],
  editableData: {},
  downloadLoading: false,
  mode: 'table',
  fileId: '',
  fileInfoVisible: false,
})

const paginationConfig = reactive({
  pageSizeOptions: ['20', '50', '100'],
  showQuickJumper: true,
  showSizeChanger: true,
  pageSize: 20,
  current: 1,
  total: 0,
  onChange: async (current: number) => {
    paginationConfig.current = current;
    await fetchList();
  },
  onShowSizeChange: async (current: number, pageSize: number) => {
    paginationConfig.pageSize = pageSize;
    await fetchList();
  }
})

const fetchList = async (query?: any) => {
  state.listLoading = true;
  try {
    const dirId = router.currentRoute.value.params?.id;
    const res = await apis.fetchFileListByFolder(dirId as string, {
      ...query,
      page: paginationConfig.current,
      page_size: paginationConfig.pageSize,
    });
    state.dirName = res.data.group_name;
    state.list = res.data.list;
    paginationConfig.current = res.data.pagination.page;
    paginationConfig.pageSize = res.data.pagination.page_size;
    paginationConfig.total = res.data.pagination.total;
  } catch (e) {
    console.error(e);
  } finally {
    state.listLoading = false;
  }
}

onMounted(async () => {
  await fetchList();
})

const columns = [
  {
    title: '文件名称',
    dataIndex: 'file_name',
    width: 250,
    ellipsis: true,
    sorter: (a: any, b: any) => a.file_name.localeCompare(b.file_name),
    slots: { customRender: 'file_name' }
  },
  {
    title: '拍摄负载',
    dataIndex: 'payload',
    width: 150,
    ellipsis: true,
  },
  {
    title: '容量大小',
    dataIndex: 'size',
    width: 150,
    ellipsis: true,
    customRender: ({ text }: any) => {
      return text > 0 ? (text / 1024 / 1024).toFixed(1) + 'M' : '--';
    }
  },
  {
    title: '创建时间',
    dataIndex: 'create_time',
    width: 200,
    sorter: (a: any, b: any) => a.create_time.localeCompare(b.create_time),
  },
  {
    title: '媒体类型',
    dataIndex: 'media_type_text',
    width: 100,
    customRender: ({ text }: any) => {
      return text || '--';
    }
  },
  {
    title: '文件类型',
    dataIndex: 'picture_type',
    width: 100,
    customRender: ({ text }: any) => {
      return text || '--';
    }
  },
  {
    title: '操作',
    dataIndex: 'actions',
    fixed: 'right',
    width: 80,
    slots: { customRender: 'action' },
  },
]

const rowClassName = (record: any, index: number) => {
  const className = []
  if ((index & 1) === 0) {
    className.push('table-striped')
  }
  return className.toString().replaceAll(',', ' ')
}

// 点击批量下载
const onClickBatchDownload = async () => {
  state.downloadLoading = true;
  try {
    const bold = await apis.batchDownloadFile({
      id: state.selectedRowKeys.join(',')
    });
    const data = new Blob([bold], { type: 'application/zip' });
    downloadFile(data, state.dirName);
  } catch (e) {
    console.error(e);
  } finally {
    state.downloadLoading = false;
  }
}

// 点击批量删除
const onClickBatchDelete = async () => {
  const canDeleteList = state.list.filter(item => state.selectedRowKeys.includes(item.file_id) && item.media_type === 2);
  const data = {
    id: canDeleteList.map(item => item.file_id).join(',')
  }
  await apis.batchDeletePicture(data);
  await fetchList()
}

// 点击搜索
const onClickSearch = async (query: any) => {
  state.query = query;
  await fetchList(query);
}

// 点击重置
const onClickReset = async (query: any) => {
  await fetchList(query);
}

// 点击返回
const onClickGoBack = () => {
  router.push({ path: '/media' })
}

// 勾选
const onSelectChange = (selectedRowKeys: string[]) => {
  state.selectedRowKeys = selectedRowKeys;
}

// 点击查看文件
const onClickLookFile = (record: any) => {
  state.fileId = record.file_id;
  state.fileInfoVisible = true;
}

// 文件信息-点击关闭
const fileInfoOnClickClose = async () => {
  state.fileId = '';
  state.fileInfoVisible = false;
  const query = state.query;
  await fetchList(query);
}

// 点击在地图上加载
const onClickCreateMapElement = async (id: string) => {
  try {
    await apis.createMapElement(id);
    const query = state.query;
    await fetchList(query);
    message.success('在地图上加载成功');
  } catch (e: any) {
    console.error(e);
  }
}

// 点击在地图上取消加载
const onClickDeleteMapElement = async (id: string) => {
  try {
    await apis.deleteMapElement(id);
    const query = state.query;
    await fetchList(query);
    message.success('在地图上取消加载成功');
  } catch (e: any) {
    console.error(e);
  }
}

// 点击重命名
const onClickRechristen = (record: any) => {
  state.editableData[record.file_id] = record;
}

// 点击保存
const onClickSave = async (record: any) => {
  delete state.editableData[record.file_id];
  await apis.updateFileName(record.file_id, { file_name: record.file_name })
  await fetchList(state.query);
}

// 点击删除
const onClickDelete = async (record: any) => {
  const data = {
    id: record.file_id
  }
  await apis.batchDeletePicture(data);
}

// 点击下载
const onClickDownload = async (record: any) => {
  state.downloadLoading = true;
  try {
    const workspaceId: string = localStorage.getItem(ELocalStorageKey.WorkspaceId) || '';
    const res = await downloadMediaFile(workspaceId, record.file_id)
    if (!res) {
      return
    }
    const data = new Blob([res])
    downloadFile(data, record.file_name)
  } catch (e) {
    console.error(e);
  } finally {
    state.downloadLoading = false;
  }
}
</script>

<style lang="scss">
.mediaDetail {
  padding: 20px;

  &-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;

    &-left {
      display: flex;
      align-items: center;
    }

    &-right {
      display: flex;
      align-items: center;

      &-text {
        display: flex;
        align-items: center;
        margin-right: 20px;
      }
    }
  }

  .fileName {
    display: flex;
    align-items: center;
    cursor: pointer;

    img {
      width: 36px;
      height: 36px;
      margin-right: 5px;
    }
  }

  &-list {
    &-name {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}

.ant-table {
  border-top: 1px solid rgb(0, 0, 0, 0.06);
  border-bottom: 1px solid rgb(0, 0, 0, 0.06);
}

.ant-table-tbody tr td {
  border: 0;
}

.table-striped {
  background-color: #f7f9fa;
}

.ant-card-body {
  padding: 0 10px 10px;
}
</style>