<template>
  <div class="dev-page">
    <!-- 工具栏 -->
    <div class="page-toolbar">
      <div class="toolbar-left">
        <h3 class="page-title">代码仓库</h3>
        <a-tag color="geekblue">{{ list.length }} 个</a-tag>
        <a-select
          v-model:value="selectedAppId"
          placeholder="全部应用"
          allow-clear
          style="width: 180px"
          @change="loadList"
        >
          <a-select-option v-for="app in appOptions" :key="app.productId" :value="app.productId">
            {{ app.productName }}
          </a-select-option>
        </a-select>
      </div>
      <div class="toolbar-right">
        <a-input-search
          v-model:value="searchText"
          placeholder="搜索仓库名称"
          style="width: 200px"
          allow-clear
          @search="loadList"
        />
        <PermissionGuard :app-id="selectedAppId" permission="canEditResource" :show-tip="true">
          <a-button type="primary" @click="showAdd = true">
            <template #icon><PlusOutlined /></template>
            添加仓库
          </a-button>
        </PermissionGuard>
      </div>
    </div>

    <!-- 仓库卡片列表 -->
    <div v-if="loading" class="card-loading">
      <a-spin size="large" />
    </div>
    <div v-else-if="list.length === 0" class="card-empty">
      <a-empty description="暂无可访问的代码仓库">
        <template v-if="!selectedAppId || getAppPermission(selectedAppId)?.canEditResource">
          <a-button type="primary" @click="showAdd = true">
            <template #icon><PlusOutlined /></template>
            添加仓库
          </a-button>
        </template>
      </a-empty>
    </div>
    <div v-else class="git-grid">
      <div
        v-for="item in filteredList"
        :key="item.resourceId"
        class="git-card"
      >
        <!-- 卡片头部 -->
        <div class="card-header">
          <div class="card-header-left">
            <div class="repo-icon">🐙</div>
            <div class="repo-info">
              <div class="repo-name">{{ item.name }}</div>
              <div class="repo-path">{{ item.gitPath }}</div>
            </div>
          </div>
          <a-dropdown :trigger="['click']">
            <a-button type="text" size="small">
              <template #icon><EllipsisOutlined /></template>
            </a-button>
            <template #overlay>
              <a-menu @click="({ key }: any) => handleMenuAction(key, item)">
                <a-menu-item key="copy-https">
                  <template #icon><CopyOutlined />复制 HTTPS</template>
                </a-menu-item>
                <a-menu-item v-if="item.gitWebUrl" key="open-web">
                  <template #icon><GlobalOutlined />网页访问</template>
                </a-menu-item>
                <a-menu-item v-if="item.isOwner || getAppPermission(item.appId)?.canEditResource" key="edit">
                  <template #icon><EditOutlined />编辑</template>
                </a-menu-item>
                <a-menu-divider v-if="item.isOwner || getAppPermission(item.appId)?.canEditResource" />
                <a-menu-item v-if="item.isOwner || getAppPermission(item.appId)?.canEditResource" key="delete" danger>
                  <template #icon><DeleteOutlined />移除</template>
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </div>

        <!-- 卡片信息区 -->
        <div class="card-info">
          <!-- Clone URL -->
          <div class="clone-section">
            <div class="clone-label">
              <GithubOutlined /> Clone URL
              <a-tag v-if="item.gitAccessLevel" size="small" :color="accessLevelColor[item.gitAccessLevel]">
                {{ accessLevelLabel[item.gitAccessLevel] || item.gitAccessLevel }}
              </a-tag>
            </div>
            <div class="clone-url-row">
              <a-tooltip :title="item.gitCloneUrl || '未配置'">
                <span class="clone-url">{{ item.gitCloneUrl || '未配置' }}</span>
              </a-tooltip>
              <a-button
                type="text"
                size="small"
                :disabled="!item.gitCloneUrl"
                @click="copyCloneUrl(item)"
              >
                <template #icon><CopyOutlined /></template>
              </a-button>
            </div>
          </div>

          <!-- 应用信息 -->
          <div v-if="item.appName" class="info-row">
            <span class="info-label"><AppstoreOutlined /></span>
            <span class="info-value">{{ item.appName }}</span>
          </div>

          <!-- 权限提示 -->
          <div v-if="!item.isOwner" class="info-row access-hint">
            <LockOutlined style="color: #faad14; font-size: 12px;" />
            <span class="access-hint-text">{{ (item.accessLevel ?? 1) >= 2 ? '协作者（开发者）' : '协作者（只读）' }}</span>
          </div>
        </div>

        <!-- 底部快捷操作 -->
        <div class="card-footer">
          <a-button
            type="link"
            size="small"
            :disabled="!item.gitCloneUrl"
            @click="copyCloneUrl(item)"
          >
            <template #icon><CopyOutlined /></template>
            复制
          </a-button>
          <a-button
            v-if="item.gitWebUrl"
            type="link"
            size="small"
            @click="openWebUrl(item.gitWebUrl!)"
          >
            <template #icon><GlobalOutlined /></template>
            访问
          </a-button>
        </div>
      </div>
    </div>

    <!-- 添加/编辑仓库弹窗 -->
    <a-modal
      v-model:open="showAdd"
      :title="editingItem ? '编辑代码仓库' : '添加代码仓库'"
      :confirm-loading="saving"
      ok-text="保存"
      cancel-text="取消"
      :mask-closable="false"
      width="520px"
      @ok="handleSave"
    >
      <a-form
        ref="formRef"
        :model="form"
        :rules="rules"
        layout="vertical"
        class="mt-4"
      >
        <a-form-item label="仓库名称" name="name">
          <a-input v-model:value="form.name" placeholder="如：Core Repository" />
        </a-form-item>

        <a-form-item label="所属应用" name="appId">
          <a-select
            v-model:value="form.appId"
            placeholder="请选择所属应用"
            :loading="loadingApps"
          >
            <a-select-option v-for="app in appOptions" :key="app.productId" :value="app.productId">
              {{ app.productName }}
            </a-select-option>
          </a-select>
        </a-form-item>

        <a-form-item label="仓库路径" name="gitPath">
          <a-input v-model:value="form.gitPath" placeholder="如：websopy/core" />
          <div class="form-tip">Gitea 上的仓库路径，格式：用户名/仓库名</div>
        </a-form-item>

        <a-form-item label="Clone URL" name="gitCloneUrl">
          <a-input v-model:value="form.gitCloneUrl" placeholder="https://git.websoft.top/websopy/core.git" />
        </a-form-item>

        <a-form-item label="Web 访问地址" name="gitWebUrl">
          <a-input v-model:value="form.gitWebUrl" placeholder="https://git.websoft.top/websopy/core" />
          <div class="form-tip">Gitea 网页访问地址，用于快速跳转到仓库页面</div>
        </a-form-item>

        <a-form-item label="访问权限" name="gitAccessLevel">
          <a-select v-model:value="form.gitAccessLevel">
            <a-select-option value="read">只读 (read)</a-select-option>
            <a-select-option value="write">读写 (write)</a-select-option>
            <a-select-option value="admin">管理员 (admin)</a-select-option>
          </a-select>
        </a-form-item>

        <a-form-item label="备注" name="remark">
          <a-textarea v-model:value="form.remark" :rows="2" placeholder="可选备注信息" />
        </a-form-item>
      </a-form>
    </a-modal>

    <!-- 删除确认弹窗 -->
    <a-modal
      v-model:open="showDelete"
      title="确认删除"
      :confirm-loading="deleting"
      ok-text="确认删除"
      cancel-text="取消"
      ok-type="danger"
      @ok="handleDelete"
    >
      <p>确定要删除仓库 <strong>{{ deletingItem?.name }}</strong> 吗？此操作不可恢复。</p>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { message } from 'ant-design-vue'
import {
  PlusOutlined,
  EllipsisOutlined,
  CopyOutlined,
  GlobalOutlined,
  EditOutlined,
  DeleteOutlined,
  LockOutlined,
  AppstoreOutlined,
  GithubOutlined,
} from '@ant-design/icons-vue'
import { pageAppResource, addAppResource, updateAppResource, removeAppResource } from '@/api/app/appResource'
import { getMyAccessibleApps } from '@/api/app/appProduct'
import type { AppResource } from '@/api/app/appResource/model'
import { enrichResourcesWithPermission } from '@/composables/useResourceAccess'
import { useAppPermission } from '@/composables/useAppPermission'
import dayjs from 'dayjs'

definePageMeta({ layout: 'developer' })
useHead({ title: '代码仓库 - 开发者中心' })

const loading = ref(false)
const saving = ref(false)
const deleting = ref(false)
const loadingApps = ref(false)
const showAdd = ref(false)
const showDelete = ref(false)
const editingItem = ref<AppResource | null>(null)
const deletingItem = ref<AppResource | null>(null)
const searchText = ref('')
const selectedAppId = ref<number | undefined>()
const appOptions = ref<any[]>([])

const list = ref<AppResource[]>([])

const formRef = ref()

const form = reactive({
  name: '',
  appId: undefined as number | undefined,
  gitPath: '',
  gitCloneUrl: '',
  gitWebUrl: '',
  gitAccessLevel: 'read',
  remark: '',
})

const rules = {
  name: [{ required: true, message: '请输入仓库名称', trigger: 'blur' }],
  appId: [{ required: true, message: '请选择所属应用', trigger: 'change' }],
  gitPath: [{ required: true, message: '请输入仓库路径', trigger: 'blur' }],
}

const accessLevelLabel: Record<string, string> = {
  read: '只读',
  write: '读写',
  admin: '管理员',
}

const accessLevelColor: Record<string, string> = {
  read: 'blue',
  write: 'green',
  admin: 'purple',
}

// 权限控制
const { getAppPermission } = useAppPermission()

// 过滤后的列表（支持搜索）
const filteredList = computed(() => {
  if (!searchText.value) return list.value
  const keyword = searchText.value.toLowerCase()
  return list.value.filter(item =>
    item.name?.toLowerCase().includes(keyword) ||
    item.gitPath?.toLowerCase().includes(keyword)
  )
})

// 加载仓库列表
async function loadList() {
  loading.value = true
  try {
    const result = await pageAppResource({
      page: 1,
      limit: 100,
      resourceType: 'git',
      appId: selectedAppId.value,
    })
    list.value = enrichResourcesWithPermission(result?.list ?? [])
  } catch (e) {
    console.error('加载仓库列表失败', e)
    message.error('加载仓库列表失败')
  } finally {
    loading.value = false
  }
}

// 加载应用列表
async function loadAppOptions() {
  loadingApps.value = true
  try {
    appOptions.value = await getMyAccessibleApps()
  } catch {
    appOptions.value = []
  } finally {
    loadingApps.value = false
  }
}

// 复制 Clone URL
async function copyCloneUrl(item: AppResource) {
  if (!item.gitCloneUrl) return
  try {
    await navigator.clipboard.writeText(item.gitCloneUrl)
    message.success('已复制 Clone URL')
  } catch {
    message.error('复制失败，请手动复制')
  }
}

// 打开 Web URL
function openWebUrl(url: string) {
  window.open(url, '_blank')
}

// 菜单操作处理
function handleMenuAction(key: string, item: AppResource) {
  switch (key) {
    case 'copy-https':
      copyCloneUrl(item)
      break
    case 'open-web':
      if (item.gitWebUrl) openWebUrl(item.gitWebUrl)
      break
    case 'edit':
      openEditModal(item)
      break
    case 'delete':
      openDeleteConfirm(item)
      break
  }
}

// 打开编辑弹窗
function openEditModal(item: AppResource) {
  editingItem.value = item
  Object.assign(form, {
    name: item.name,
    appId: item.appId,
    gitPath: item.gitPath,
    gitCloneUrl: item.gitCloneUrl,
    gitWebUrl: item.gitWebUrl,
    gitAccessLevel: item.gitAccessLevel || 'read',
    remark: item.remark,
  })
  showAdd.value = true
}

// 打开删除确认弹窗
function openDeleteConfirm(item: AppResource) {
  deletingItem.value = item
  showDelete.value = true
}

// 保存仓库
async function handleSave() {
  try {
    await formRef.value.validate()
  } catch {
    return
  }

  saving.value = true
  try {
    const data: Partial<AppResource> = {
      resourceType: 'git',
      name: form.name,
      appId: form.appId,
      gitPath: form.gitPath,
      gitCloneUrl: form.gitCloneUrl,
      gitWebUrl: form.gitWebUrl,
      gitAccessLevel: form.gitAccessLevel,
      remark: form.remark,
      status: 'running',
    }

    if (editingItem.value?.resourceId) {
      data.resourceId = editingItem.value.resourceId
      await updateAppResource(data)
      message.success('更新成功')
    } else {
      await addAppResource(data)
      message.success('添加成功')
    }

    showAdd.value = false
    resetForm()
    await loadList()
  } catch (e: any) {
    message.error(e.message || '保存失败')
  } finally {
    saving.value = false
  }
}

// 删除仓库
async function handleDelete() {
  if (!deletingItem.value?.resourceId) return

  deleting.value = true
  try {
    await removeAppResource(deletingItem.value.resourceId)
    message.success('删除成功')
    showDelete.value = false
    deletingItem.value = null
    await loadList()
  } catch (e: any) {
    message.error(e.message || '删除失败')
  } finally {
    deleting.value = false
  }
}

// 重置表单
function resetForm() {
  editingItem.value = null
  Object.assign(form, {
    name: '',
    appId: undefined,
    gitPath: '',
    gitCloneUrl: '',
    gitWebUrl: '',
    gitAccessLevel: 'read',
    remark: '',
  })
}

// 监听弹窗关闭，重置表单
watch(showAdd, (val) => {
  if (!val) resetForm()
})

// 页面初始化
onMounted(() => {
  loadAppOptions()
  loadList()
})
</script>

<style scoped>
.dev-page {
  padding: 24px;
  max-width: 1400px;
}

/* 工具栏 */
.page-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
  gap: 16px;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.page-title {
  font-size: 18px;
  font-weight: 600;
  margin: 0;
}

/* 卡片网格 */
.git-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap: 16px;
}

.git-card {
  background: #fff;
  border: 1px solid #e8e8e8;
  border-radius: 10px;
  overflow: hidden;
  transition: all 0.2s;
}

.git-card:hover {
  border-color: #1677ff;
  box-shadow: 0 2px 12px rgba(22, 119, 255, 0.1);
}

/* 卡片头部 */
.card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid #f5f5f5;
}

.card-header-left {
  display: flex;
  align-items: center;
  gap: 10px;
}

.repo-icon {
  font-size: 28px;
  width: 40px;
  height: 40px;
  background: #f0f5ff;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.repo-info {
  min-width: 0;
}

.repo-name {
  font-size: 15px;
  font-weight: 600;
  color: #333;
  margin-bottom: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.repo-path {
  font-size: 12px;
  color: #888;
}

/* 卡片信息区 */
.card-info {
  padding: 14px 16px;
}

.clone-section {
  margin-bottom: 12px;
}

.clone-label {
  font-size: 12px;
  color: #666;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.clone-url-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #f9f9f9;
  border-radius: 6px;
  padding: 8px 12px;
}

.clone-url {
  flex: 1;
  font-size: 12px;
  font-family: 'Monaco', 'Menlo', monospace;
  color: #333;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.clone-url:hover {
  color: #1677ff;
}

.info-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  font-size: 13px;
}

.info-label {
  color: #888;
  font-size: 14px;
}

.info-value {
  color: #333;
}

.access-hint {
  background: #fffbe6;
  border-radius: 6px;
  padding: 6px 10px;
  margin-top: 10px;
}

.access-hint-text {
  font-size: 12px;
  color: #7c4a00;
}

/* 卡片底部 */
.card-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-top: 1px solid #f5f5f5;
  background: #fafafa;
}

/* 空状态 */
.card-empty,
.card-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 24px;
  background: #fff;
  border: 1px solid #e8e8e8;
  border-radius: 10px;
}

/* 表单提示 */
.form-tip {
  font-size: 12px;
  color: #888;
  margin-top: 4px;
}

.mt-4 {
  margin-top: 16px;
}
</style>
