<template>
    <LayoutContent v-loading="loading" :title="activeName">
        <template #toolbar>
            <el-row :gutter="5">
                <el-col :span="20">
                    <div>
                        <el-button @click="changeTag('all')" type="primary" :plain="activeTag !== 'all'">
                            {{ $t('app.all') }}
                        </el-button>
                        <div v-for="item in tags" :key="item.key" style="display: inline">
                            <el-button
                                class="tag-button"
                                @click="changeTag(item.key)"
                                type="primary"
                                :plain="activeTag !== item.key"
                            >
                                {{ item.name }}
                            </el-button>
                        </div>
                    </div>
                </el-col>
                <el-col :span="4">
                    <div style="float: right">
                        <el-input
                            class="table-button"
                            v-model="searchReq.name"
                            clearable
                            @clear="search()"
                            suffix-icon="Search"
                            @keyup.enter="search()"
                            @blur="search()"
                            :placeholder="$t('commons.button.search')"
                        ></el-input>
                    </div>
                </el-col>
            </el-row>
        </template>
        <template #rightButton>
            <el-button @click="sync" type="primary" link v-if="mode === 'installed'">{{ $t('app.sync') }}</el-button>
        </template>
        <template #main>
            <div class="divider"></div>
            <el-row :gutter="5">
                <el-col v-for="(installed, index) in data" :key="index" :span="12">
                    <div class="app-card">
                        <el-row :gutter="24">
                            <el-col :span="4">
                                <div class="icon">
                                    <el-avatar
                                        shape="square"
                                        :size="66"
                                        :src="'data:image/png;base64,' + installed.app.icon"
                                    />
                                </div>
                            </el-col>
                            <el-col :span="20">
                                <div class="a-detail">
                                    <div class="d-name">
                                        <span class="name">{{ installed.name }}</span>
                                        <span class="status">
                                            <el-popover
                                                v-if="installed.status === 'Error'"
                                                placement="bottom"
                                                :width="400"
                                                trigger="hover"
                                                :content="installed.message"
                                            >
                                                <template #reference>
                                                    <Status :key="installed.status" :status="installed.status"></Status>
                                                </template>
                                            </el-popover>
                                            <span v-else>
                                                <Status :key="installed.status" :status="installed.status"></Status>
                                            </span>
                                        </span>

                                        <el-button
                                            class="h-button"
                                            type="primary"
                                            plain
                                            round
                                            size="small"
                                            @click="openBackups(installed.id, installed.name)"
                                            v-if="mode === 'installed'"
                                        >
                                            {{ $t('app.backup') }}
                                        </el-button>
                                        <el-button
                                            class="h-button"
                                            type="primary"
                                            plain
                                            round
                                            size="small"
                                            @click="openOperate(installed, 'update')"
                                            v-if="mode === 'update'"
                                        >
                                            {{ $t('app.update') }}
                                        </el-button>
                                    </div>
                                    <div class="d-description">
                                        <el-tag>{{ $t('app.version') }}：{{ installed.version }}</el-tag>
                                        <el-tag>HTTP{{ $t('app.port') }}：{{ installed.httpPort }}</el-tag>
                                        <el-tag v-if="installed.httpsPort > 0">
                                            HTTPS{{ $t('app.port') }}：{{ installed.httpsPort }}
                                        </el-tag>
                                        <div class="description">
                                            <span>{{ $t('app.areadyRun') }}： {{ getAge(installed.createdAt) }}</span>
                                        </div>
                                    </div>
                                    <div class="divider"></div>
                                    <div class="d-button" v-if="mode === 'installed'">
                                        <el-button
                                            v-for="(button, key) in buttons"
                                            :key="key"
                                            type="primary"
                                            plain
                                            round
                                            size="small"
                                            @click="button.click(installed)"
                                            :disabled="button.disabled && button.disabled(installed)"
                                        >
                                            {{ button.label }}
                                        </el-button>
                                    </div>
                                </div>
                            </el-col>
                        </el-row>
                    </div>
                </el-col>
            </el-row>
        </template>
    </LayoutContent>
    <Backups ref="backupRef" @close="search" />
    <AppResources ref="checkRef" />
    <AppDelete ref="deleteRef" @close="search" />
    <AppParams ref="appParamRef" />
    <AppUpdate ref="updateRef" @close="search" />
</template>

<script lang="ts" setup>
import {
    SearchAppInstalled,
    InstalledOp,
    SyncInstalledApp,
    AppInstalledDeleteCheck,
    GetAppTags,
} from '@/api/modules/app';
import LayoutContent from '@/layout/layout-content.vue';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import i18n from '@/lang';
import { ElMessage, ElMessageBox } from 'element-plus';
import Backups from './backup/index.vue';
import AppResources from './check/index.vue';
import AppDelete from './delete/index.vue';
import AppParams from './detail/index.vue';
import AppUpdate from './update/index.vue';
import { App } from '@/api/interface/app';
import Status from '@/components/status/index.vue';
import { getAge } from '@/utils/util';
import { useRouter } from 'vue-router';

let data = ref<any>();
let loading = ref(false);
let timer: NodeJS.Timer | null = null;
const paginationConfig = reactive({
    currentPage: 1,
    pageSize: 20,
    total: 0,
});
let open = ref(false);
let operateReq = reactive({
    installId: 0,
    operate: '',
    detailId: 0,
});
const backupRef = ref();
const checkRef = ref();
const deleteRef = ref();
const appParamRef = ref();
const updateRef = ref();
let tags = ref<App.Tag[]>([]);
let activeTag = ref('all');
let searchReq = reactive({
    page: 1,
    pageSize: 15,
    name: '',
    tags: [],
    updated: false,
});
const router = useRouter();
let activeName = ref(i18n.global.t('app.installed'));
let mode = ref('installed');

const sync = () => {
    loading.value = true;
    SyncInstalledApp()
        .then(() => {
            ElMessage.success(i18n.global.t('app.syncSuccess'));
            search();
        })
        .finally(() => {
            loading.value = false;
        });
};

const changeTag = (key: string) => {
    searchReq.tags = [];
    activeTag.value = key;
    if (key !== 'all') {
        searchReq.tags = [key];
    }
    search();
};

const search = () => {
    searchReq.page = paginationConfig.currentPage;
    searchReq.pageSize = paginationConfig.pageSize;
    SearchAppInstalled(searchReq).then((res) => {
        data.value = res.data.items;
        paginationConfig.total = res.data.total;
    });
    GetAppTags().then((res) => {
        tags.value = res.data;
    });
};

const openOperate = (row: any, op: string) => {
    operateReq.installId = row.id;
    operateReq.operate = op;
    if (op == 'update') {
        updateRef.value.acceptParams(row.id, row.name);
    } else if (op == 'delete') {
        AppInstalledDeleteCheck(row.id).then(async (res) => {
            const items = res.data;
            if (res.data && res.data.length > 0) {
                checkRef.value.acceptParams({ items: items });
            } else {
                deleteRef.value.acceptParams(row);
            }
        });
    } else {
        onOperate(op);
    }
};

const operate = async () => {
    open.value = false;
    loading.value = true;
    await InstalledOp(operateReq)
        .then(() => {
            ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
            search();
        })
        .finally(() => {
            loading.value = false;
        });
};

const onOperate = async (operation: string) => {
    ElMessageBox.confirm(
        i18n.global.t('app.operatorHelper', [i18n.global.t('app.' + operation)]),
        i18n.global.t('app.' + operation),
        {
            confirmButtonText: i18n.global.t('commons.button.confirm'),
            cancelButtonText: i18n.global.t('commons.button.cancel'),
            type: 'info',
        },
    ).then(() => {
        operate();
    });
};

const buttons = [
    {
        label: i18n.global.t('app.sync'),
        click: (row: any) => {
            openOperate(row, 'sync');
        },
    },
    {
        label: i18n.global.t('app.update'),
        click: (row: any) => {
            openOperate(row, 'update');
        },
        disabled: (row: any) => {
            return !row.canUpdate;
        },
    },
    {
        label: i18n.global.t('app.restart'),
        click: (row: any) => {
            openOperate(row, 'restart');
        },
    },
    {
        label: i18n.global.t('app.up'),
        click: (row: any) => {
            openOperate(row, 'up');
        },
        disabled: (row: any) => {
            return row.status === 'Running';
        },
    },
    {
        label: i18n.global.t('app.down'),
        click: (row: any) => {
            openOperate(row, 'down');
        },
    },
    {
        label: i18n.global.t('app.delete'),
        click: (row: any) => {
            openOperate(row, 'delete');
        },
    },
    {
        label: i18n.global.t('app.detail'),
        click: (row: any) => {
            openParam(row.id);
        },
    },
];

const openBackups = (installId: number, installName: string) => {
    let params = {
        appInstallId: installId,
        appInstallName: installName,
    };
    backupRef.value.acceptParams(params);
};

const openParam = (installId: number) => {
    appParamRef.value.acceptParams({ id: installId });
};

onMounted(() => {
    const path = router.currentRoute.value.path;
    if (path == '/apps/update') {
        activeName.value = i18n.global.t('app.canUpdate');
        mode.value = 'update';
        searchReq.updated = true;
    }
    search();
    timer = setInterval(() => {
        search();
    }, 1000 * 8);
});

onUnmounted(() => {
    clearInterval(Number(timer));
});
</script>

<style scoped lang="scss">
@import '../index.scss';
</style>
