package routes

import (
	"github.com/gofiber/fiber/v2"

	"github.com/break/junhong_cmp_fiber/internal/handler/admin"
	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/pkg/openapi"
)

func registerStorageRoutes(router fiber.Router, handler *admin.StorageHandler, doc *openapi.Generator, basePath string) {
	storage := router.Group("/storage")
	groupPath := basePath + "/storage"

	Register(storage, doc, groupPath, "POST", "/batch-download-urls", handler.GetBatchDownloadURLs, RouteSpec{
		Summary: "批量获取文件下载预签名 URL",
		Description: `## 文件展示流程

本接口用于批量获取对象存储文件的预签名下载 URL。由于存储桶为私有访问，文件不能直接通过路径访问，必须通过预签名 URL 才能展示。

### 为什么需要这个接口

对象存储使用私有 Bucket，文件路径（file_key）本身无法直接访问。前端持有的 file_key 只是文件标识，需要通过本接口换取带签名的临时访问 URL，才能在 ` + "`" + `<img>` + "`" + ` 或下载链接中使用。

### 完整使用流程

1. **业务接口返回 file_key**（存储在数据库中的文件路径标识）
2. **调用本接口** 传入所有需要展示的 file_key 列表
3. **使用返回的 URL** 直接赋值给 ` + "`" + `<img src>` + "`" + ` 或下载链接，图片/文件内容直接从对象存储加载，不经过后端

### 列表页批量展示示例

` + "```" + `javascript
// 假设列表数据中每条记录有 avatar_key 字段
const listData = await api.get('/customers');

// 收集所有 file_key（过滤掉空值）
const fileKeys = listData.map(item => item.avatar_key).filter(Boolean);

// 一次性换取所有下载 URL
const { data } = await api.post('/storage/batch-download-urls', {
  file_keys: fileKeys
});

// 渲染时通过 map 取对应 URL
listData.forEach(item => {
  item.avatarUrl = data.urls[item.avatar_key] ?? '';
});
` + "```" + `

### 单个文件展示示例

` + "```" + `javascript
// 详情页只有一个文件时，也走批量接口（保持一致）
const { data } = await api.post('/storage/batch-download-urls', {
  file_keys: [record.license_key]
});

const licenseUrl = data.urls[record.license_key];
` + "```" + `

### 前端缓存建议

预签名 URL 有效期 **24 小时**，建议在内存中缓存，避免同一页面重复请求：

` + "```" + `javascript
const urlCache = new Map(); // key: file_key, value: { url, expireAt }

async function getFileUrl(fileKey) {
  const cached = urlCache.get(fileKey);
  if (cached && cached.expireAt > Date.now()) {
    return cached.url;
  }
  const { data } = await api.post('/storage/batch-download-urls', {
    file_keys: [fileKey]
  });
  const url = data.urls[fileKey];
  urlCache.set(fileKey, { url, expireAt: Date.now() + data.expires_in * 1000 * 0.9 });
  return url;
}
` + "```" + `

### 注意事项

- 单次请求最多 **50 个** file_key
- 预签名 URL 有效期 **24 小时**，过期后需重新获取
- file_key 不存在时对应的 URL 生成会失败，整个请求返回错误
- 图片/文件内容直接从对象存储加载到浏览器，**不经过后端**，不消耗服务器带宽`,
		Tags:   []string{"对象存储"},
		Input:  new(dto.GetBatchDownloadURLsRequest),
		Output: new(dto.GetBatchDownloadURLsResponse),
		Auth:   true,
	})

	Register(storage, doc, groupPath, "POST", "/upload-url", handler.GetUploadURL, RouteSpec{
		Summary: "获取文件上传预签名 URL",
		Description: `## 文件上传流程

本接口用于获取对象存储的预签名上传 URL，实现前端直传文件到对象存储。

### 完整流程

1. **调用本接口** 获取预签名 URL 和 file_key
2. **使用预签名 URL 上传文件** 发起 PUT 请求直接上传到对象存储
3. **调用业务接口** 使用 file_key 调用相关业务接口（如 ICCID 导入）

### 前端上传示例

` + "```" + `javascript
// 1. 获取预签名 URL
const { data } = await api.post('/storage/upload-url', {
  file_name: 'cards.xlsx',
  content_type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  purpose: 'iot_import'
});

// 2. 上传文件到对象存储
await fetch(data.upload_url, {
  method: 'PUT',
  headers: { 'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' },
  body: file
});

// 3. 调用业务接口
await api.post('/iot-cards/import', {
  carrier_id: 1,
  batch_no: 'BATCH-2025-01',
  file_key: data.file_key
});
` + "```" + `

### purpose 可选值

| 值 | 说明 | 生成路径格式 |
|---|------|-------------|
| iot_import | ICCID/设备导入 (Excel) | imports/YYYY/MM/DD/uuid.xlsx |
| batch_purchase | 资产套餐批量订购 (CSV) | batch-purchases/YYYY/MM/DD/uuid.csv |
| device_batch_allocation | 设备批量分配代理或套餐系列 (CSV) | device-batch-allocations/YYYY/MM/DD/uuid.csv |
| export | 数据导出 | exports/YYYY/MM/DD/uuid.xlsx |
| attachment | 附件上传 | attachments/YYYY/MM/DD/uuid.ext |

### 注意事项

- 预签名 URL 有效期 **15 分钟**，请及时使用
- 上传时 Content-Type 需与请求时一致
- file_key 在上传成功后永久有效，用于后续业务接口调用
- 上传失败时可重新调用本接口获取新的 URL`,
		Tags:   []string{"对象存储"},
		Input:  new(dto.GetUploadURLRequest),
		Output: new(dto.GetUploadURLResponse),
		Auth:   true,
	})
}
