<template>
  <div class="app-installer-page">
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">
          <n-icon><Icon icon="tabler:upload" /></n-icon>
          {{ t('App Installer') }}
        </h1>
        <p class="page-description">{{ t('Upload and install applications to your local Jingrow environment') }}</p>
      </div>
      <div class="header-actions">
        <n-button
          type="primary"
          @click="goToMarket"
          :theme-overrides="{ colorHover: '#3b82f6', colorPressed: '#2563eb' }"
        >
          <template #icon>
            <n-icon><Icon icon="tabler:shopping-cart" /></n-icon>
          </template>
          {{ t('App Marketplace') }}
        </n-button>
      </div>
    </div>

    <div class="upload-section">
      <n-card :title="t('Upload App Package')" class="upload-card">
        <n-upload
          ref="uploadRef"
          :file-list="fileList"
          :max="1"
          accept=".zip,.tar.gz,.tgz,.gz"
          :on-before-upload="beforeUpload"
          :on-change="handleFileChange"
          :custom-request="customUpload"
          :disabled="uploading"
        >
          <n-upload-dragger>
            <div class="upload-content" v-if="fileList.length === 0">
              <n-icon size="48" :depth="3">
                <Icon icon="tabler:cloud-upload" />
              </n-icon>
              <n-text style="font-size: 16px">
                {{ uploading ? t('Uploading...') : t('Click or drag package file to this area to upload') }}
              </n-text>
              <n-p depth="3" style="margin: 8px 0 0 0">
                {{ t('Support for ZIP, TAR.GZ, and GZ format') }}
              </n-p>
            </div>
          </n-upload-dragger>
        </n-upload>
        
        <div v-if="fileList.length > 0" class="file-info-card">
          <n-alert type="info" :bordered="false">
            <template #header>
              <div class="file-info-header">
                <n-icon size="20" color="#2080f0">
                  <Icon icon="tabler:file-zip" />
                </n-icon>
                <strong>{{ t('Selected Package') }}</strong>
              </div>
            </template>
            <n-space vertical>
              <n-text><strong>{{ t('File Name') }}:</strong> {{ fileList[0].name }}</n-text>
              <n-text v-if="fileList[0].file" depth="3">
                <strong>{{ t('Size') }}:</strong> {{ formatFileSize(fileList[0].file.size) }}
              </n-text>
            </n-space>
          </n-alert>
        </div>
        
        <div class="upload-actions" v-if="fileList.length > 0">
          <n-space>
            <n-button @click="clearFiles" :disabled="uploading">
              {{ t('Clear') }}
            </n-button>
            <n-button type="primary" @click="startUpload" :loading="uploading" :disabled="uploading">
              <template #icon>
                <n-icon><Icon icon="tabler:upload" /></n-icon>
              </template>
              {{ t('Install App') }}
            </n-button>
          </n-space>
        </div>
      </n-card>
    </div>

    <div class="local-apps-section" v-if="localApps.length > 0">
      <n-card :title="t('Local Apps Available')" class="local-apps-card">
        <n-data-table
          :columns="localAppsColumns"
          :data="localApps"
          :loading="loadingLocalApps"
          :pagination="false"
          :bordered="false"
        />
      </n-card>
    </div>

    <n-modal v-model:show="showProgressModal" preset="card" style="width: 500px">
      <template #header>
        <h3>{{ t('Installing App') }}</h3>
      </template>
      
      <div class="progress-content">
        <n-progress
          :percentage="installProgress"
          :status="installStatus"
          :show-indicator="true"
        />
        <n-text class="progress-text">{{ installMessage }}</n-text>
      </div>
      
      <template #action>
        <n-button @click="showProgressModal = false" :disabled="installing">
          {{ installing ? t('Installing...') : t('Close') }}
        </n-button>
      </template>
    </n-modal>

  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, h } from 'vue'
import {
  NIcon, NButton, NSpace, NCard, NUpload, NUploadDragger, NText, NP,
  NModal, NProgress, NDataTable, useMessage, NAlert,
  type UploadFileInfo, type DataTableColumns
} from 'naive-ui'
import { Icon } from '@iconify/vue'
import axios from 'axios'
import { useRouter } from 'vue-router'
import { t } from '@/shared/i18n'

const fileList = ref<UploadFileInfo[]>([])
const uploading = ref(false)
const installing = ref(false)
const installProgress = ref(0)
const installMessage = ref('')
const installStatus = ref<'success' | 'error' | 'info'>('info')
const showProgressModal = ref(false)

const localApps = ref<any[]>([])
const loadingLocalApps = ref(false)

const message = useMessage()
const uploadRef = ref()
const router = useRouter()

const goToMarket = () => {
  router.push('/app-marketplace')
}

const localAppsColumns: DataTableColumns<any> = [
  {
    title: t('App Name'),
    key: 'name',
    width: 150
  },
  {
    title: t('Title'),
    key: 'title',
    width: 200
  },
  {
    title: t('Publisher'),
    key: 'publisher',
    width: 150
  },
  {
    title: t('Description'),
    key: 'description',
    ellipsis: true
  },
  {
    title: t('Actions'),
    key: 'actions',
    width: 120,
    render: (row: any) => {
      return h(NButton, {
        type: 'primary',
        size: 'small',
        onClick: () => installLocalApp(row.name)
      }, {
        default: () => t('Install')
      })
    }
  }
]

const beforeUpload = (data: { file: UploadFileInfo }) => {
  const file = data.file.file
  if (!file) return false
  
  const fileName = file.name.toLowerCase()
  const allowedExtensions = ['.zip', '.tar.gz', '.tgz', '.gz']
  const isValidFile = allowedExtensions.some(ext => fileName.endsWith(ext))
  
  if (!isValidFile) {
    message.error(t('Only ZIP and TAR.GZ files are supported'))
    return false
  }
  
  return true
}

const handleFileChange = (options: { fileList: UploadFileInfo[] }) => {
  fileList.value = options.fileList
}

const customUpload = async (_options: any) => {
  return Promise.resolve()
}

const startUpload = async () => {
  if (fileList.value.length === 0) {
    message.error(t('Please select a file first'))
    return
  }
  
  const file = fileList.value[0].file
  if (!file) {
    message.error(t('File not found'))
    return
  }
  
  // 统一使用应用安装流程，不再区分扩展包和应用包
  const apiEndpoint = '/jingrow/install/upload'
  
  try {
    uploading.value = true
    installing.value = true
    showProgressModal.value = true
    installProgress.value = 0
    installMessage.value = t('Preparing upload...')
    installStatus.value = 'info'
    
    const formData = new FormData()
    formData.append('file', file)
    
    installProgress.value = 30
    installMessage.value = t('Uploading file...')
    const response = await axios.post(apiEndpoint, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      onUploadProgress: (progressEvent) => {
        if (progressEvent.total) {
          const progress = Math.round((progressEvent.loaded * 70) / progressEvent.total) + 30
          installProgress.value = Math.min(progress, 100)
        }
      }
    })
    
    installProgress.value = 100
    installMessage.value = t('Installation completed!')
    installStatus.value = 'success'
    
    if (response.data.success) {
      clearFiles()
      
      const resultAppName = response.data.app_name
      message.success(t('Package \'{0}\' installed successfully').replace('{0}', resultAppName))
    } else {
      throw new Error(response.data.error || t('Installation failed'))
    }
    
  } catch (error: any) {
    installProgress.value = 100
    installMessage.value = t('Installation failed!')
    installStatus.value = 'error'
    
    const errorDetail = error.response?.data?.detail || 
                        error.response?.data?.message || 
                        error.message || 
                        t('Upload failed')
    
    message.error(errorDetail)
  } finally {
    uploading.value = false
    installing.value = false
  }
}

const clearFiles = () => {
  fileList.value = []
  uploadRef.value?.clear()
}

const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}

const loadLocalApps = async () => {
  loadingLocalApps.value = true
  try {
    const base = (import.meta as any).env.VITE_LOCAL_API_URL || ''
    const response = await axios.get(`${base}/jingrow/local-apps`)
    
    if (response.data.success) {
      localApps.value = response.data.data.apps
    } else {
      message.error(response.data.detail || t('Failed to load local apps'))
    }
  } catch (error: any) {
    message.error(error?.response?.data?.detail || error?.message || t('Failed to load local apps'))
  } finally {
    loadingLocalApps.value = false
  }
}

const installLocalApp = async (appName: string) => {
  try {
    const base = (import.meta as any).env.VITE_LOCAL_API_URL || ''
    const response = await axios.post(`${base}/jingrow/install-local/${appName}`)
    
    if (response.data.success) {
      message.success(t('App \'{0}\' installed successfully').replace('{0}', appName))
      await loadLocalApps()
    } else {
      message.error(response.data.detail || t('Failed to install app'))
    }
  } catch (error: any) {
    message.error(error?.response?.data?.detail || error?.message || t('Failed to install app'))
  }
}

onMounted(() => {
  loadLocalApps()
})
</script>

<style scoped>
.app-installer-page {
  padding: 16px 24px;
  width: 100%;
  margin: 0;
  min-height: 100vh;
}

.page-header {
  margin-bottom: 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.header-content {
  flex: 1;
  text-align: center;
}

.header-actions {
  flex-shrink: 0;
}

.page-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 0 0 8px 0;
  font-size: 28px;
  font-weight: 600;
  color: #1f2937;
}

.page-description {
  margin: 0;
  color: #6b7280;
  font-size: 16px;
}

.upload-section {
  margin-bottom: 32px;
}

.upload-card {
  border: 2px dashed #d1d5db;
  transition: all 0.2s ease;
}

.upload-card:hover {
  border-color: #3b82f6;
}

.file-info-card {
  margin-top: 16px;
}

.file-info-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.upload-content {
  padding: 40px 20px;
  text-align: center;
}

.upload-actions {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #e5e7eb;
  display: flex;
  justify-content: flex-end;
}

.progress-content {
  padding: 20px 0;
}

.progress-text {
  display: block;
  text-align: center;
  margin-top: 12px;
  font-size: 14px;
}

.local-apps-section {
  margin-top: 32px;
}

.local-apps-card {
  border: 1px solid #e5e7eb;
}

@media (max-width: 1200px) {
  .app-installer-page {
    padding: 12px 16px;
  }
}

@media (max-width: 768px) {
  .app-installer-page {
    padding: 8px 12px;
  }
  
  .page-header {
    margin-bottom: 16px;
    flex-direction: column;
    align-items: stretch;
  }
  
  .header-content {
    margin-bottom: 16px;
  }
  
  .header-actions {
    align-self: center;
  }
  
  .upload-section {
    margin-bottom: 16px;
  }
  
  .local-apps-section {
    margin-top: 16px;
  }
}
</style>
