import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi';
import { FileService } from '@/server/modules/files/file.service';
import { MinioService } from '@/server/modules/files/minio.service';
import { ErrorSchema } from '@/server/utils/errorHandler';
import { AppDataSource } from '@/server/data-source';
import { AuthContext } from '@/server/types/context';
import { authMiddleware } from '@/server/middleware/auth.middleware';

// 创建分片上传策略请求Schema
const CreateMultipartUploadPolicyDto = z.object({
fileKey: z.string().openapi({
  description: '文件键名',
  example: 'documents/report.pdf'
}),
totalSize: z.coerce.number().int().positive().openapi({
  description: '文件总大小(字节)',
  example: 10485760
}),
partSize: z.coerce.number().int().positive().openapi({
  description: '分片大小(字节)',
  example: 5242880
}),
type: z.string().max(50).nullable().optional().openapi({
  description: '文件类型',
  example: 'application/pdf'
}),
name: z.string().max(255).openapi({
  description: '文件名称',
  example: '项目计划书.pdf'
})
});

// 创建分片上传策略路由定义
const createMultipartUploadPolicyRoute = createRoute({
  method: 'post',
  path: '/',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': { schema: CreateMultipartUploadPolicyDto }
      }
    }
  },
  responses: {
    200: {
      description: '生成分片上传策略成功',
      content: {
        'application/json': {
          schema: z.object({
            uploadId: z.string().openapi({
              description: '分片上传ID',
              example: '123e4567-e89b-12d3-a456-426614174000'
            }),
            bucket: z.string().openapi({
              description: '存储桶名称',
              example: 'my-bucket'
            }),
            key: z.string().openapi({
              description: '文件键名',
              example: 'documents/report.pdf'
            }),
            host: z.string().openapi({
              description: 'MinIO主机地址',
              example: 'minio.example.com'
            }),
            partUrls: z.array(z.string()).openapi({
              description: '分片上传URL列表',
              example: [
                'https://minio.example.com/my-bucket/documents/report.pdf?uploadId=123e4567-e89b-12d3-a456-426614174000&partNumber=1',
                'https://minio.example.com/my-bucket/documents/report.pdf?uploadId=123e4567-e89b-12d3-a456-426614174000&partNumber=2'
              ]
            })
          })
        }
      }
    },
    400: {
      description: '请求参数错误',
      content: { 'application/json': { schema: ErrorSchema } }
    },
    500: {
      description: '服务器错误',
      content: { 'application/json': { schema: ErrorSchema } }
    }
  }
});

// 创建文件服务实例
const fileService = new FileService(AppDataSource);

// 创建路由实例
const app = new OpenAPIHono<AuthContext>().openapi(createMultipartUploadPolicyRoute, async (c) => {
try {
  const data = await c.req.json();
  const user = c.get('user');
  // 计算分片数量
  const partCount = Math.ceil(data.totalSize / data.partSize);
  const result = await fileService.createMultipartUploadPolicy({
    ...data,
    uploadUserId: user.id
  }, partCount);
  
  return c.json({
    uploadId: result.uploadId,
    bucket: result.bucket,
    key: result.key,
    host: `${process.env.MINIO_USE_SSL ? 'https' : 'http'}://${process.env.MINIO_ENDPOINT}:${process.env.MINIO_PORT}`,
    partUrls: result.uploadUrls
  }, 200);
} catch (error) {
  const message = error instanceof Error ? error.message : '生成分片上传策略失败';
  return c.json({ code: 500, message }, 500);
}
});

export default app;