import { query, transaction } from '../database';
import type {
  User,
  CriteriaTemplate,
  CriteriaItem,
  Project,
  ProjectFile,
  ProjectWebsite,
  Evaluation,
  EvaluationScore,
  EvaluationFeedback,
  ProjectWithDetails,
  EvaluationWithDetails,
  CriteriaTemplateWithItems,
} from '../models';

// 用戶相關操作
export class UserService {
  static async create(userData: Omit<User, 'id' | 'created_at' | 'updated_at'>) {
    const sql = `
      INSERT INTO users (email, username, password_hash, full_name, avatar_url, role, is_active, email_verified_at, last_login_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      userData.email,
      userData.username,
      userData.password_hash,
      userData.full_name,
      userData.avatar_url,
      userData.role,
      userData.is_active,
      userData.email_verified_at,
      userData.last_login_at,
    ]);
    return result;
  }

  static async findByEmail(email: string): Promise<User | null> {
    const sql = 'SELECT * FROM users WHERE email = ?';
    const rows = await query(sql, [email]) as User[];
    return rows.length > 0 ? rows[0] : null;
  }

  static async findById(id: number): Promise<User | null> {
    const sql = 'SELECT * FROM users WHERE id = ?';
    const rows = await query(sql, [id]) as User[];
    return rows.length > 0 ? rows[0] : null;
  }

  static async updateLastLogin(id: number) {
    const sql = 'UPDATE users SET last_login_at = NOW() WHERE id = ?';
    await query(sql, [id]);
  }
}

// 評分標準模板相關操作
export class CriteriaTemplateService {
  static async create(templateData: Omit<CriteriaTemplate, 'id' | 'created_at' | 'updated_at'>) {
    const sql = `
      INSERT INTO criteria_templates (user_id, name, description, is_default, is_public, total_weight)
      VALUES (?, ?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      templateData.user_id,
      templateData.name,
      templateData.description,
      templateData.is_default,
      templateData.is_public,
      templateData.total_weight,
    ]);
    return result;
  }

  static async findById(id: number): Promise<CriteriaTemplate | null> {
    const sql = 'SELECT * FROM criteria_templates WHERE id = ?';
    const rows = await query(sql, [id]) as CriteriaTemplate[];
    return rows.length > 0 ? rows[0] : null;
  }

  static async findByUserId(userId: number): Promise<CriteriaTemplate[]> {
    const sql = 'SELECT * FROM criteria_templates WHERE user_id = ? ORDER BY created_at DESC';
    return await query(sql, [userId]) as CriteriaTemplate[];
  }

  static async findDefault(): Promise<CriteriaTemplate | null> {
    const sql = 'SELECT * FROM criteria_templates WHERE is_default = 1 LIMIT 1';
    const rows = await query(sql) as CriteriaTemplate[];
    return rows.length > 0 ? rows[0] : null;
  }

  static async findWithItems(id: number): Promise<CriteriaTemplateWithItems | null> {
    const template = await this.findById(id);
    if (!template) return null;

    const itemsSql = 'SELECT * FROM criteria_items WHERE template_id = ? ORDER BY sort_order';
    const items = await query(itemsSql, [id]) as CriteriaItem[];

    return { ...template, items };
  }

  static async update(id: number, templateData: Partial<CriteriaTemplate>) {
    const fields = Object.keys(templateData).map(key => `${key} = ?`).join(', ');
    const values = Object.values(templateData);
    const sql = `UPDATE criteria_templates SET ${fields}, updated_at = NOW() WHERE id = ?`;
    await query(sql, [...values, id]);
  }

  static async delete(id: number) {
    const sql = 'DELETE FROM criteria_templates WHERE id = ?';
    await query(sql, [id]);
  }
}

// 評分項目相關操作
export class CriteriaItemService {
  static async create(itemData: Omit<CriteriaItem, 'id' | 'created_at' | 'updated_at'>) {
    const sql = `
      INSERT INTO criteria_items (template_id, name, description, weight, max_score, sort_order)
      VALUES (?, ?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      itemData.template_id,
      itemData.name,
      itemData.description,
      itemData.weight,
      itemData.max_score,
      itemData.sort_order,
    ]);
    return result;
  }

  static async getAllTemplates(): Promise<CriteriaTemplateWithItems[]> {
    const sql = `
      SELECT t.*, 
             JSON_ARRAYAGG(
               JSON_OBJECT(
                 'id', i.id,
                 'name', i.name,
                 'description', i.description,
                 'weight', i.weight,
                 'maxScore', i.max_score,
                 'sort_order', i.sort_order
               )
             ) as items
      FROM criteria_templates t
      LEFT JOIN criteria_items i ON t.id = i.template_id
      GROUP BY t.id
      ORDER BY t.created_at DESC
    `;
    
    const rows = await query(sql) as any[];
    
    return rows.map(row => {
      let items = [];
      if (row.items) {
        try {
          // 檢查 items 是否已經是對象數組
          if (Array.isArray(row.items)) {
            items = row.items;
          } else if (typeof row.items === 'string') {
            items = JSON.parse(row.items);
          } else {
            console.log('items 類型:', typeof row.items, row.items);
            items = [];
          }
          // 手動排序項目
          items.sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0));
        } catch (error) {
          console.error('解析 items JSON 失敗:', error);
          console.error('原始 items 數據:', row.items);
          items = [];
        }
      }
      
      return {
        ...row,
        items
      };
    });
  }

  static async findByTemplateId(templateId: number): Promise<CriteriaItem[]> {
    const sql = 'SELECT * FROM criteria_items WHERE template_id = ? ORDER BY sort_order';
    const rows = await query(sql, [templateId]) as any[];
    
    // 映射資料庫欄位到前端期望的格式
    return rows.map(row => ({
      id: row.id,
      template_id: row.template_id,
      name: row.name,
      description: row.description,
      weight: Number(row.weight) || 0,
      maxScore: Number(row.max_score) || 10, // 映射 max_score 到 maxScore 並轉換為數字
      sort_order: row.sort_order,
      created_at: row.created_at,
      updated_at: row.updated_at
    }));
  }

  static async update(id: number, itemData: Partial<CriteriaItem>) {
    const fields = Object.keys(itemData).map(key => `${key} = ?`).join(', ');
    const values = Object.values(itemData);
    const sql = `UPDATE criteria_items SET ${fields}, updated_at = NOW() WHERE id = ?`;
    await query(sql, [...values, id]);
  }

  static async delete(id: number) {
    const sql = 'DELETE FROM criteria_items WHERE id = ?';
    await query(sql, [id]);
  }

  static async deleteByTemplateId(templateId: number) {
    const sql = 'DELETE FROM criteria_items WHERE template_id = ?';
    await query(sql, [templateId]);
  }
}

// 專案相關操作
export class ProjectService {
  static async create(projectData: Omit<Project, 'id' | 'created_at' | 'updated_at'>) {
    const sql = `
      INSERT INTO projects (user_id, template_id, title, description, status, analysis_started_at, analysis_completed_at)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      projectData.user_id,
      projectData.template_id,
      projectData.title,
      projectData.description,
      projectData.status,
      projectData.analysis_started_at,
      projectData.analysis_completed_at,
    ]);
    return result;
  }

  static async findById(id: number): Promise<Project | null> {
    const sql = 'SELECT * FROM projects WHERE id = ?';
    const rows = await query(sql, [id]) as Project[];
    return rows.length > 0 ? rows[0] : null;
  }

  static async findByUserId(userId: number, limit = 20, offset = 0): Promise<Project[]> {
    const sql = `
      SELECT * FROM projects 
      WHERE user_id = ? 
      ORDER BY created_at DESC 
      LIMIT ? OFFSET ?
    `;
    return await query(sql, [userId, limit, offset]) as Project[];
  }

  static async findWithDetails(id: number): Promise<ProjectWithDetails | null> {
    const project = await this.findById(id);
    if (!project) return null;

    const template = await CriteriaTemplateService.findById(project.template_id);
    if (!template) return null;

    const files = await ProjectFileService.findByProjectId(id);
    const websites = await ProjectWebsiteService.findByProjectId(id);
    const evaluation = await EvaluationService.findByProjectId(id);

    return {
      ...project,
      template,
      files,
      websites,
      evaluation,
    };
  }

  static async update(id: number, projectData: Partial<Project>) {
    const fields = Object.keys(projectData).map(key => `${key} = ?`).join(', ');
    const values = Object.values(projectData);
    const sql = `UPDATE projects SET ${fields}, updated_at = NOW() WHERE id = ?`;
    await query(sql, [...values, id]);
  }

  static async delete(id: number) {
    const sql = 'DELETE FROM projects WHERE id = ?';
    await query(sql, [id]);
  }
}

// 專案文件相關操作
export class ProjectFileService {
  static async create(fileData: Omit<ProjectFile, 'id' | 'created_at' | 'updated_at'>) {
    const sql = `
      INSERT INTO project_files (project_id, original_name, file_name, file_path, file_size, file_type, mime_type, upload_status, upload_progress)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      fileData.project_id,
      fileData.original_name,
      fileData.file_name,
      fileData.file_path,
      fileData.file_size,
      fileData.file_type,
      fileData.mime_type,
      fileData.upload_status,
      fileData.upload_progress,
    ]);
    return result;
  }

  static async findByProjectId(projectId: number): Promise<ProjectFile[]> {
    const sql = 'SELECT * FROM project_files WHERE project_id = ? ORDER BY created_at';
    return await query(sql, [projectId]) as ProjectFile[];
  }

  static async updateStatus(id: number, status: ProjectFile['upload_status'], progress?: number) {
    const sql = 'UPDATE project_files SET upload_status = ?, upload_progress = ?, updated_at = NOW() WHERE id = ?';
    await query(sql, [status, progress || 0, id]);
  }

  static async delete(id: number) {
    const sql = 'DELETE FROM project_files WHERE id = ?';
    await query(sql, [id]);
  }
}

// 專案網站相關操作
export class ProjectWebsiteService {
  static async create(websiteData: Omit<ProjectWebsite, 'id' | 'created_at' | 'updated_at'>) {
    const sql = `
      INSERT INTO project_websites (project_id, url, title, description, status)
      VALUES (?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      websiteData.project_id,
      websiteData.url,
      websiteData.title,
      websiteData.description,
      websiteData.status,
    ]);
    return result;
  }

  static async findByProjectId(projectId: number): Promise<ProjectWebsite[]> {
    const sql = 'SELECT * FROM project_websites WHERE project_id = ? ORDER BY created_at';
    return await query(sql, [projectId]) as ProjectWebsite[];
  }

  static async updateStatus(id: number, status: ProjectWebsite['status']) {
    const sql = 'UPDATE project_websites SET status = ?, updated_at = NOW() WHERE id = ?';
    await query(sql, [status, id]);
  }

  static async delete(id: number) {
    const sql = 'DELETE FROM project_websites WHERE id = ?';
    await query(sql, [id]);
  }
}

// 評審相關操作
export class EvaluationService {
  static async create(evaluationData: Omit<Evaluation, 'id' | 'created_at' | 'updated_at'>) {
    const sql = `
      INSERT INTO evaluations (project_id, overall_score, max_possible_score, grade, analysis_duration, ai_model_version, status, error_message)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      evaluationData.project_id,
      evaluationData.overall_score,
      evaluationData.max_possible_score,
      evaluationData.grade,
      evaluationData.analysis_duration,
      evaluationData.ai_model_version,
      evaluationData.status,
      evaluationData.error_message,
    ]);
    return result;
  }

  static async findById(id: number): Promise<Evaluation | null> {
    const sql = 'SELECT * FROM evaluations WHERE id = ?';
    const rows = await query(sql, [id]) as Evaluation[];
    return rows.length > 0 ? rows[0] : null;
  }

  static async findByProjectId(projectId: number): Promise<Evaluation | null> {
    const sql = 'SELECT * FROM evaluations WHERE project_id = ? ORDER BY created_at DESC LIMIT 1';
    const rows = await query(sql, [projectId]) as Evaluation[];
    return rows.length > 0 ? rows[0] : null;
  }

  static async findWithDetails(id: number): Promise<EvaluationWithDetails | null> {
    const evaluation = await this.findById(id);
    if (!evaluation) return null;

    const project = await ProjectService.findById(evaluation.project_id);
    if (!project) return null;

    const scoresSql = `
      SELECT es.*, ci.name as criteria_item_name, ci.description as criteria_item_description
      FROM evaluation_scores es
      JOIN criteria_items ci ON es.criteria_item_id = ci.id
      WHERE es.evaluation_id = ?
      ORDER BY ci.sort_order
    `;
    const scores = await query(scoresSql, [id]) as (EvaluationScore & { criteria_item: CriteriaItem })[];

    const feedback = await EvaluationFeedbackService.findByEvaluationId(id);

    return {
      ...evaluation,
      project,
      scores,
      feedback,
    };
  }

  static async update(id: number, evaluationData: Partial<Evaluation>) {
    const fields = Object.keys(evaluationData).map(key => `${key} = ?`).join(', ');
    const values = Object.values(evaluationData);
    const sql = `UPDATE evaluations SET ${fields}, updated_at = NOW() WHERE id = ?`;
    await query(sql, [...values, id]);
  }

  static async delete(id: number) {
    const sql = 'DELETE FROM evaluations WHERE id = ?';
    await query(sql, [id]);
  }
}

// 評分結果相關操作
export class EvaluationScoreService {
  static async create(scoreData: Omit<EvaluationScore, 'id' | 'created_at'>) {
    const sql = `
      INSERT INTO evaluation_scores (evaluation_id, criteria_item_id, score, max_score, weight, weighted_score, percentage)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      scoreData.evaluation_id,
      scoreData.criteria_item_id,
      scoreData.score,
      scoreData.max_score,
      scoreData.weight,
      scoreData.weighted_score,
      scoreData.percentage,
    ]);
    return result;
  }

  static async findByEvaluationId(evaluationId: number): Promise<EvaluationScore[]> {
    const sql = 'SELECT * FROM evaluation_scores WHERE evaluation_id = ?';
    return await query(sql, [evaluationId]) as EvaluationScore[];
  }

  static async deleteByEvaluationId(evaluationId: number) {
    const sql = 'DELETE FROM evaluation_scores WHERE evaluation_id = ?';
    await query(sql, [evaluationId]);
  }
}

// 評語相關操作
export class EvaluationFeedbackService {
  static async create(feedbackData: Omit<EvaluationFeedback, 'id' | 'created_at'>) {
    const sql = `
      INSERT INTO evaluation_feedback (evaluation_id, criteria_item_id, feedback_type, content, sort_order)
      VALUES (?, ?, ?, ?, ?)
    `;
    const result = await query(sql, [
      feedbackData.evaluation_id,
      feedbackData.criteria_item_id,
      feedbackData.feedback_type,
      feedbackData.content,
      feedbackData.sort_order,
    ]);
    return result;
  }

  static async findByEvaluationId(evaluationId: number): Promise<EvaluationFeedback[]> {
    const sql = 'SELECT * FROM evaluation_feedback WHERE evaluation_id = ? ORDER BY sort_order';
    return await query(sql, [evaluationId]) as EvaluationFeedback[];
  }

  static async deleteByEvaluationId(evaluationId: number) {
    const sql = 'DELETE FROM evaluation_feedback WHERE evaluation_id = ?';
    await query(sql, [evaluationId]);
  }
}
