import { NextRequest } from "next/server";
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/lib/auth";
import { RecordingService } from "@/lib/services/recording.service";
import { ApiResponseHandler } from "@/lib/utils/api-response";
import { AuthenticationError, ValidationError } from "@/lib/errors/app-error";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  region: process.env.AWS_REGION || "us-east-1",
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
  },
});

export async function POST(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);

    if (!session?.user?.id) {
      throw new AuthenticationError();
    }

    const formData = await request.formData();
    const audioFile = formData.get("audio") as File;
    const audioUrl = formData.get("audioUrl") as string;
    const duration = formData.get("duration") as string;
    const title = formData.get("title") as string;
    const fileSize = formData.get("fileSize") as string;
    const mimeType = formData.get("mimeType") as string;

    let finalAudioUrl: string;
    let finalFileSize: number;
    let finalMimeType: string;

    // 如果有音频文件，先上传到 S3
    if (audioFile) {
      if (!duration) {
        throw new ValidationError("缺少录音时长");
      }

      // 验证文件类型
      if (!audioFile.type.startsWith("audio/")) {
        throw new ValidationError("文件类型必须是音频");
      }

      // 验证文件大小 (50MB 限制)
      const maxSize = 50 * 1024 * 1024;
      if (audioFile.size > maxSize) {
        throw new ValidationError("文件大小不能超过 50MB");
      }

      // 生成唯一的文件名
      const userId = session.user.id;
      const timestamp = Date.now();
      const uniqueFileName = `recordings/${userId}/${timestamp}-recording.webm`;

      // 上传到 S3
      const arrayBuffer = await audioFile.arrayBuffer();
      const buffer = Buffer.from(arrayBuffer);

      const command = new PutObjectCommand({
        Bucket: process.env.AWS_S3_BUCKET!,
        Key: uniqueFileName,
        Body: buffer,
        ContentType: audioFile.type,
      });

      await s3.send(command);

      // 生成 S3 URL - 修复格式
      const region = process.env.AWS_REGION || "us-east-1";
      const bucketName = process.env.AWS_S3_BUCKET!;

      // 根据区域生成正确的 S3 URL
      let s3Url: string;
      if (region === "us-east-1") {
        // us-east-1 使用特殊格式
        s3Url = `https://${bucketName}.s3.amazonaws.com/${uniqueFileName}`;
      } else {
        // 其他区域使用标准格式
        s3Url = `https://${bucketName}.s3.${region}.amazonaws.com/${uniqueFileName}`;
      }

      finalAudioUrl = s3Url;
      finalFileSize = audioFile.size;
      finalMimeType = audioFile.type;
    } else if (audioUrl) {
      // 如果提供了 S3 URL，直接使用
      if (!fileSize || !mimeType) {
        throw new ValidationError("缺少文件信息");
      }

      // 验证 S3 URL 格式
      if (
        !audioUrl.startsWith("https://") ||
        !audioUrl.includes("amazonaws.com")
      ) {
        throw new ValidationError("无效的音频文件URL");
      }

      finalAudioUrl = audioUrl;
      finalFileSize = parseInt(fileSize);
      finalMimeType = mimeType;
    } else {
      throw new ValidationError("缺少音频文件或URL");
    }

    if (!duration) {
      throw new ValidationError("缺少录音时长");
    }

    // 验证文件大小 (50MB 限制)
    const maxSize = 50 * 1024 * 1024;
    if (finalFileSize > maxSize) {
      throw new ValidationError("文件大小不能超过 50MB");
    }

    // 验证标题
    const recordingTitle =
      title?.trim() || `录音 ${new Date().toLocaleString("zh-CN")}`;
    if (recordingTitle.length > 100) {
      throw new ValidationError("录音标题不能超过100个字符");
    }

    // 创建录音记录
    const recording = await RecordingService.createRecording({
      title: recordingTitle,
      audioUrl: finalAudioUrl,
      duration: parseInt(duration),
      fileSize: finalFileSize,
      mimeType: finalMimeType,
      userId: session.user.id,
    });

    return ApiResponseHandler.created(recording);
  } catch (error) {
    return ApiResponseHandler.error(error as Error);
  }
}
