<template>
  <div class="q-pa-md">
    <div class="q-gutter-sm row items-start">
        <q-breadcrumbs>
          <q-breadcrumbs-el icon="widgets" label="アプリ管理" />
        </q-breadcrumbs>
    </div>
    <q-table title="Treats" :rows="rows" :columns="columns" row-key="id" :filter="filter" :loading="loading" :pagination="pagination">

      <template v-slot:top>
        <q-btn color="primary" :disable="loading" label="新規" @click="showAddAppDialog" />
        <q-space />
        <q-input borderless dense filled debounce="300" v-model="filter" placeholder="検索">
          <template v-slot:append>
            <q-icon name="search" />
          </template>
        </q-input>
      </template>
      <template v-slot:body-cell-name="prop">
        <q-td :props="prop">
          <q-btn flat dense :label="prop.row.name" @click="toEditFlowPage(prop.row)" ></q-btn>
        </q-td>
      </template>
      <template v-slot:body-cell-url="prop">
        <q-td :props="prop">
          <a :href="prop.row.url" target="_blank" :title="prop.row.name" >
            {{ prop.row.url  }}
          </a>
        </q-td>
      </template>
      <template v-slot:body-cell-actions="p">
        <q-td :props="p">
          <table-action-menu :row="p.row" :actions="actionList" />
        </q-td>
      </template>
    </q-table>

    <show-dialog v-model:visible="showSelectApp" name="アプリ選択" @close="closeSelectAppDialog" min-width="50vw" min-height="50vh" :ok-btn-auto-close="false" :ok-btn-loading="isAdding">
      <template v-slot:toolbar>
        <q-input dense debounce="300" v-model="dgFilter" placeholder="検索" clearable>
          <template v-slot:before>
            <q-icon name="search" />
          </template>
        </q-input>
      </template>
      <app-select-box ref="appDialog" name="アプリ" type="single" :filter="dgFilter" :filterInitRowsFunc="filterInitRows" />
    </show-dialog>

    
    <show-dialog v-model:visible="showVersionHistory" :name="targetRow?.name + 'のバージョン履歴'" @close="closeHistoryDg" min-width="30vw" :ok-btn-auto-close="false" :ok-btn-loading="isAdding"
      ok-btn-label="選択">
      <version-history ref="versionDialog" :app="targetRow" />
    </show-dialog>

    <q-dialog v-model="deleteDialog" persistent>
      <q-card>
        <q-card-section class="row items-center">
          <q-icon name="warning" color="warning" size="2em" />
          <span class="q-ml-sm">削除してもよろしいですか？</span>
        </q-card-section>

        <q-card-actions align="right">
          <q-btn flat label="Cancel" color="primary" v-close-popup />
          <q-btn flat label="OK" color="primary" :loading="deleteUserLoading" @click="deleteApp" />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, reactive } from 'vue';
import { useQuasar } from 'quasar'
import { api } from 'boot/axios';
import { useAuthStore } from 'stores/useAuthStore';
import { useFlowEditorStore } from 'stores/flowEditor';
import { router } from 'src/router';
import { date } from 'quasar'
import { IManagedApp, IAppDisplay, IAppVersion } from 'src/types/AppTypes';
import ShowDialog from 'src/components/ShowDialog.vue';
import AppSelectBox from 'src/components/AppSelectBox.vue';
import TableActionMenu from 'components/TableActionMenu.vue';
import VersionHistory from 'components/dialog/VersionHistory.vue';

const authStore = useAuthStore();
const numberStringSorting = (a: string, b: string) => parseInt(a, 10) - parseInt(b, 10);

const columns = [
  { name: 'id', label: 'アプリID', field: 'id', align: 'left', sortable: true, sort: numberStringSorting },
  { name: 'name', label: 'アプリ名', field: 'name', align: 'left', sortable: true },
  { name: 'url', label: 'URL', field: 'url', align: 'left', sortable: true },
  { name: 'updateUser', label: '最後更新者', field: (row: IAppDisplay) => row.updateUser.fullName, align: 'left', sortable: true},
  { name: 'updateTime', label: '最後更新日', field: 'updateTime', align: 'left', sortable: true},
  { name: 'version', label: 'バージョン', field: 'version', align: 'left', sortable: true, sort: numberStringSorting },
  { name: 'actions', label: '', field: 'actions' }
];

const pagination = ref({ sortBy: 'id', descending: true, rowsPerPage: 20 });
const loading = ref(false);
const filter = ref('');
const dgFilter = ref('');
const rows = ref<IAppDisplay[]>([]);
const targetRow = ref<IAppDisplay>();
const rowIds = new Set<string>();

const $q = useQuasar()
const store = useFlowEditorStore();
const appDialog = ref();
const versionDialog = ref();
const showSelectApp=ref(false);
const showVersionHistory=ref(false);
const isAdding = ref(false);
const deleteDialog = ref(false);
const deleteUserLoading = ref(false);

const actionList =  [
  { label: '設定', icon: 'account_tree', action: toEditFlowPage },
  { label: '履歴', icon: 'history', action: showHistory },
  { separator: true },
  { label: '削除', icon: 'delete_outline', class: 'text-red', action: removeRow },
];

const getApps = async () => {
  loading.value = true;
  rowIds.clear();
  try {
    const { data } = await api.get('api/apps');
    rows.value = data.data.map((item: IManagedApp) => {
      rowIds.add(item.appid);
      return appToAppDisplay(item)
    }).sort((a: IAppDisplay, b: IAppDisplay) => a.sortId - b.sortId); // set default order
  } catch (error) {
    $q.notify({
      icon: 'error',
      color: 'negative',
      message: 'アプリ一覧の読み込みに失敗しました'
    });
  } finally {
    loading.value = false;
  }
}

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

watch(() => authStore.currentDomain.id, async () => {
  await getApps();
});

const filterInitRows = (row: {id: string}) => {
  return !rowIds.has(row.id);
}

const showAddAppDialog = () => {
  showSelectApp.value = true;
  dgFilter.value = ''
}

const closeSelectAppDialog = async (val: 'OK'|'Cancel') => {
  showSelectApp.value = true;
  if (val == 'OK' && appDialog.value.selected[0]) {
      isAdding.value = true;
      toEditFlowPage(appDialog.value.selected[0]);
  }
  showSelectApp.value = false;
  isAdding.value = false;
}

function removeRow(app:IAppDisplay) {
  targetRow.value = app;
  deleteDialog.value = true;
}

const deleteApp = async () => {
  deleteUserLoading.value = true;
  try {
    await api.delete(`api/apps/${targetRow.value?.id}`);
    await getApps();
  } catch (error) {
    $q.notify({
      icon: 'error',
      color: 'negative',
      message: 'アプリの削除に失敗しました'
    });
  } finally {
    deleteUserLoading.value = false;
    deleteDialog.value = false;
  }
}

function showHistory(app:IAppDisplay) {
  targetRow.value = app;
  showVersionHistory.value = true;
  dgFilter.value = ''
}

const closeHistoryDg = async (val: 'OK'|'Cancel') => {
  showVersionHistory.value = true;
  if (val == 'OK' && versionDialog.value.selected[0]) {
      isAdding.value = true;
      await api.put(`api/appversions/${targetRow.value?.id}/${versionDialog.value.selected[0].id}`)
      await getApps();
  }
  showVersionHistory.value = false;
  isAdding.value = false;
}

const appToAppDisplay = (app: IManagedApp) => {
  const user = app.updateuser;
  return {
    id: app.appid,
    sortId: parseInt(app.appid, 10),
    name: app.appname,
    url: `${app.domainurl}/k/${app.appid}`,
    version: app.version,
    updateTime:date.formatDate(app.update_time, 'YYYY/MM/DD HH:mm'),
    updateUser: {
      id: user.id,
      firstName: user.first_name,
      lastName: user.last_name,
      fullNameSearch: (user.last_name + user.first_name).toLowerCase(),
      fullName: user.last_name + ' ' + user.first_name,
      email: user.email,
      isSuperuser: user.is_superuser,
      isActive: user.is_active,
    }
  } as IAppDisplay
}

async function toEditFlowPage(app:IAppDisplay) {
  store.setApp({
    appId: app.id,
    name: app.name
  });
  store.selectFlow(undefined);
  await router.push('/FlowChart/' + app.id);
};
</script>
