//
//  APIModels.swift - 对齐 api-server 实际返回结构
//

import Foundation

// MARK: - API Envelope (ResponseInterceptor wraps all responses)

struct APIEnvelope<T: Decodable>: Decodable {
    let success: Bool
    let data: T
    let timestamp: String?
}

// MARK: - Pagination

struct PaginationMeta: Codable {
    let page: Int
    let limit: Int
    let total: Int
}

struct PaginatedResponse<T: Decodable>: Decodable {
    let data: [T]
    let meta: PaginationMeta
}

// MARK: - Waitlist

struct WaitlistEntry: Codable, Identifiable {
    let id: String
    let nickname: String?
    let email: String
    let devices: [String]?
    let interests: [String]?
    let painpoint: String?
    let willingBeta: Bool?
    let createdAt: String?
}

struct WaitlistCreateRequest: Codable {
    let email: String
    let nickname: String?
    let devices: [String]?
    let interests: [String]?
    let painpoint: String?
    let willingBeta: Bool?

    init(email: String, nickname: String? = nil, devices: [String]? = nil,
         interests: [String]? = nil, painpoint: String? = nil, willingBeta: Bool = true) {
        self.email = email
        self.nickname = nickname
        self.devices = devices
        self.interests = interests
        self.painpoint = painpoint
        self.willingBeta = willingBeta
    }
}

struct WaitlistResponse: Codable {
    let success: Bool?
    let message: String?
    let data: WaitlistEntry?
}

struct WaitlistStats: Codable {
    let total: Int?
    let today: Int?
    let deviceBreakdown: [String: Int]?
    let interestBreakdown: [String: Int]?
}

// MARK: - Auth

struct AuthResponse: Codable {
    let accessToken: String
    let refreshToken: String?
    let user: AuthUser?
}

struct AuthUser: Codable, Identifiable {
    let id: String
    let email: String?
    let nickname: String?
    let avatarUrl: String?
    let role: String?
    let status: String?
    let onboardingCompleted: Bool?
}

struct AppleAuthRequest: Codable {
    let identityToken: String
    let authorizationCode: String?
    let fullName: AppleFullName?
    let nonce: String?

    struct AppleFullName: Codable {
        let givenName: String?
        let familyName: String?
    }
}

struct RefreshRequest: Codable {
    let refreshToken: String
}

// MARK: - User Profile (matches GET /users/me with include: profile + preferences)

struct UserProfileResponse: Codable, Identifiable {
    let id: String
    let email: String?
    let nickname: String?
    let avatarUrl: String?
    let role: String?
    let status: String?
    let onboardingCompleted: Bool?
    let createdAt: String?
    let profile: UserProfileData?
    let preferences: UserPreferences?
}

struct UserProfileData: Codable {
    let learningIdentity: String?
    let learningDirection: String?
    let bio: String?
    let currentGoal: String?
}

struct UserPreferences: Codable, Equatable {
    let preferredMethods: [String]?
    let defaultFocusMinutes: Int?
    let aiSuggestionLevel: String?
    let language: String?
    let appearance: String?
    let notificationEnabled: Bool?
}

struct UpdateProfileRequest: Codable {
    let nickname: String?
    let avatarUrl: String?
}

struct UpdatePreferencesRequest: Codable {
    let preferredMethods: [String]?
    let defaultFocusMinutes: Int?
    let aiSuggestionLevel: String?
    let language: String?
    let appearance: String?
    let notificationEnabled: Bool?
}

struct UpdateProfileDataRequest: Codable {
    let learningIdentity: String?
    let learningDirection: String?
    let bio: String?
    let currentGoal: String?
}

// MARK: - Knowledge Base (matches Prisma KnowledgeBase model)

struct KnowledgeBase: Codable, Identifiable {
    let id: String
    let userId: String?
    let title: String
    let description: String?
    let coverKey: String?
    let coverUrl: String?
    let coverType: String?
    let visibility: String?
    let isPinned: Bool?
    let ownerType: String?
    let isVerified: Bool?
    let status: String?
    let itemCount: Int?
    let lastStudiedAt: String?
    let createdAt: String?
    let updatedAt: String?
}

struct CreateKnowledgeBaseRequest: Codable {
    let title: String
    let description: String?
    var coverKey: String? = nil
}

struct KnowledgeBaseCoverUploadResult {
    let fileId: String
    let objectKey: String
}

// MARK: - Knowledge Items (matches Prisma KnowledgeItem model)

struct KnowledgeItem: Codable, Identifiable, Hashable {
    let id: String
    let userId: String?
    let knowledgeBaseId: String?
    let parentId: String?
    let itemType: String?
    let title: String
    let content: String?
    let summary: String?
    let sourceType: String?
    let sourceRef: String?
    let orderIndex: Int?
    let status: String?
    let createdAt: String?
    let updatedAt: String?
}

struct CreateKnowledgeItemRequest: Codable {
    let knowledgeBaseId: String
    let title: String
    let content: String?
    let itemType: String?
}

struct UpdateKnowledgeItemRequest: Codable {
    let title: String?
    let content: String?
    let summary: String?
}

// MARK: - Active Recall (matches ActiveRecallQuestion / Answer models)

struct ActiveRecallQuestion: Codable, Identifiable {
    let id: String
    let userId: String?
    let knowledgeItemId: String?
    let questionText: String
    let difficulty: String?
    let createdBy: String?
    let createdAt: String?
}

struct ActiveRecallAnswer: Codable, Identifiable {
    let id: String
    let userId: String?
    let questionId: String?
    let answerType: String?
    let answerText: String?
    let submittedAt: String?
}

struct SubmitAnswerRequest: Codable {
    let answerText: String
}

// MARK: - AI Analysis (matches AiAnalysisResult model)

struct AIAnalysisRequest: Codable {
    let questionText: String?
    let knowledgeItemContent: String?
    let userAnswer: String?
    let text: String?
    let type: String?
}

struct AIAnalysisResult: Codable, Identifiable {
    let id: String
    let userId: String?
    let summary: String?
    let masteryScore: Int?
    let strengths: [String]?
    let weaknesses: [String]?
    let suggestions: [String]?
    let nextActions: [String]?
    let rawResult: AIAnalysisRawResult?
    let createdAt: String?
}

struct AIAnalysisRawResult: Codable {
    let score: Double?
    let analysis: String?
    let focusItems: [String]?
}

// MARK: - Learning Session (matches Prisma LearningSession model)

struct LearningSession: Codable, Identifiable {
    let id: String
    let userId: String?
    let knowledgeBaseId: String?
    let knowledgeItemId: String?
    let mode: String?
    let status: String?
    let startedAt: String?
    let endedAt: String?
    let durationSeconds: Int?
    let focusMinutes: Int?
    let createdAt: String?
}

struct CreateLearningSessionRequest: Codable {
    let knowledgeBaseId: String?
    let knowledgeItemId: String?
    let mode: String?
}

// MARK: - Review (matches ReviewCard / ReviewLog models)

struct ReviewCard: Codable, Identifiable {
    let id: String
    let userId: String?
    let knowledgeItemId: String?
    let frontText: String
    let backText: String?
    let difficulty: String?
    let status: String?
    let nextReviewAt: String?
    let intervalDays: Int?
    let easeFactor: Double?
    let repetitionCount: Int?
    let lapseCount: Int?
}

struct SubmitReviewRequest: Codable {
    let rating: String
    let responseText: String?
}

// MARK: - Focus Items (matches Prisma FocusItem model)

struct FocusItem: Codable, Identifiable {
    let id: String
    let userId: String?
    let knowledgeBaseId: String?
    let knowledgeItemId: String?
    let title: String
    let reason: String?
    let suggestion: String?
    let priority: String?
    let status: String?
    let masteryScore: Int?
    let dueAt: String?
    let completedAt: String?
    let createdAt: String?
}

// MARK: - Activity (matches DailyLearningActivity + summary aggregation)

struct ActivitySummary: Codable {
    let totalMinutes: Int?
    let totalCardsReviewed: Int?
    let activeDays: Int?
    let dailyAverage: Int?
}

struct ActivityHeatmap: Codable {
    // Dictionary of "YYYY-MM-DD" -> durationSeconds
}

// MARK: - Feedback

struct FeedbackCreateRequest: Codable {
    let category: String
    let content: String
    let email: String?

    init(category: String = "general", content: String, email: String? = nil) {
        self.category = category
        self.content = content
        self.email = email
    }
}

struct FeedbackData: Codable, Identifiable {
    let id: String?
    let category: String?
    let content: String?
    let status: String?
    let createdAt: String?
}

// MARK: - Notifications (matches Prisma Notification model)

struct NotificationItem: Codable, Identifiable {
    let id: String
    let userId: String?
    let type: String
    let title: String
    let content: String?
    let data: [String: String]?
    let readAt: String?
    let createdAt: String?
}

// MARK: - Generic

struct GenericSuccessResponse: Codable {
    let success: Bool?
    let message: String?
}

struct BatchDeleteResponse: Codable {
    let success: Bool?
    let message: String?
    let count: Int?
}

// MARK: - Quiz

struct Quiz: Codable, Identifiable {
    let id: String
    let knowledgeBaseId: String?
    let title: String?
    let description: String?
    let questionCount: Int?
    let sourceType: String?
    let status: String?
    let createdAt: String?
    let questions: [QuizQuestion]?
}

struct QuizQuestion: Codable, Identifiable {
    let id: String
    let quizId: String?
    let type: String?
    let stem: String?
    let options: [String]?
    let answer: String?
    let explanation: String?
    let orderIndex: Int?
}

struct QuizAttempt: Codable, Identifiable {
    let id: String
    let quizId: String?
    let totalQuestions: Int?
    let correctCount: Int?
    let score: Int?
    let startedAt: String?
    let finishedAt: String?
    let answers: [QuizAnswer]?
    let quiz: QuizInfo?
}

struct QuizInfo: Codable { let title: String? }

struct QuizAnswer: Codable, Identifiable {
    let id: String
    let attemptId: String?
    let questionId: String?
    let userAnswer: String?
    let isCorrect: Bool?
    let answeredAt: String?
    let question: QuizQuestion?
}

struct QuizGenerateRequest: Codable {
    let knowledgeBaseId: String
    let questionCount: Int
}

struct QuizSubmitRequest: Codable {
    let attemptId: String
    let answers: [QuizAnswerItem]
}

struct QuizAnswerItem: Codable {
    let questionId: String
    let answer: String
}

struct QuizSubmitResponse: Codable {
    let score: Int?
    let correctCount: Int?
    let totalQuestions: Int?
    let finishedAt: String?
}

// MARK: - RAG Chat

struct ChatSession: Codable, Identifiable {
    let id: String
    let userId: String?
    let knowledgeBaseId: String?
    let title: String?
    let createdAt: String?
    let updatedAt: String?
}

struct ChatMessage: Codable, Identifiable {
    let id: String
    let sessionId: String?
    let role: String
    let content: String
    let tokens: Int?
    let createdAt: String?
    let citations: [ChatCitation]?
}

struct ChatCitation: Codable, Identifiable {
    let id: String
    let chunkId: String?
    let sourceTitle: String?
    let excerptText: String?
    let pageNumber: Int?
}

struct CreateSessionRequest: Codable {
    let knowledgeBaseId: String
    let title: String?
}

struct SendMessageRequest: Codable {
    let content: String
}

struct SendMessageResponse: Codable {
    let id: String?
    let role: String?
    let content: String?
    let tokens: Int?
    let blocked: Bool?
    let message: String?
    let citations: [ChatCitation]?
}

// MARK: - Document Import

struct CreateImportRequest: Codable {
    let knowledgeBaseId: String
    let fileName: String?
    let sourceType: String?
    let rawText: String?
}

struct ImportStatusResponse: Codable {
    let id: String
    let status: String?
    let fileName: String?
    let knowledgeBaseId: String?
    let errorMessage: String?
    let itemCount: Int?
}

// MARK: - Import Candidate

struct ImportCandidate: Codable, Identifiable {
    let id: String
    let sourceId: String?
    let title: String?
    let content: String?
    let status: String?
    let confidence: Double?
    let createdAt: String?
}

struct BatchAcceptRequest: Codable {
    let sourceId: String
}

// MARK: - Knowledge Source

struct KnowledgeSource: Codable, Identifiable {
    let id: String
    let knowledgeBaseId: String?
    let title: String?
    let originalFilename: String?
    let type: String?
    let mimeType: String?
    let parseStatus: String?
    let indexStatus: String?
    let textLength: Int?
    let createdAt: String?
}

struct AddSourceRequest: Codable {
    let fileId: String?
    let type: String?
    let title: String?
}

// MARK: - Learning Activity

struct ActivityTrend: Codable {
    let date: String?
    let value: Double?
    let label: String?
}

struct ActivityStreak: Codable {
    let currentStreak: Int?
    let longestStreak: Int?
    let lastActiveDate: String?
}

struct ActivityRecommendation: Codable, Identifiable {
    var id: String { title ?? UUID().uuidString }
    let title: String?
    let description: String?
    let type: String?
    let priority: String?
}

// MARK: - File Upload (COS presigned URL flow)

struct FileUploadUrlRequest: Codable {
    let filename: String
    let mimeType: String
    let sizeBytes: Int
}

struct FileUploadUrlResponse: Codable {
    let uploadUrl: String
    let objectKey: String
    let bucket: String
    let region: String
    let expiresIn: Int
}

struct FileConfirmUploadRequest: Codable {
    let objectKey: String
    let checksum: String?
}

struct FileConfirmUploadResponse: Codable {
    let id: String
    let filename: String
    let objectKey: String
    let sizeBytes: Int
}

struct FileDetailResponse: Codable {
    let file: FileInfo
    let downloadUrl: String
}

struct FileInfo: Codable {
    let id: String
    let filename: String
    let mimeType: String?
    let sizeBytes: Int
    let objectKey: String?
    let storagePath: String?
    let createdAt: String?
}
