import VocabService from '../services/vocabService.js';

function extractHashedUserId(req) {
  return req.headers?.userid;
}

class VocabController {
  constructor() {
    this.service = new VocabService();

    this.listLanguages = this._wrapWithUser((userId) => this.service.listLanguages(userId));
    this.listAllLanguages = this._wrapWithUser(() => this.service.listAllLanguages());
    this.createLanguage = this._wrapWithUser((userId, req) => this.service.createLanguage(userId, req.body), { successStatus: 201 });
    this.subscribe = this._wrapWithUser((userId, req) => this.service.subscribeByShareCode(userId, req.body), { successStatus: 201 });
    this.getLanguage = this._wrapWithUser((userId, req) => this.service.getLanguage(userId, req.params.languageId));

    this.listChapters = this._wrapWithUser((userId, req) => this.service.listChapters(userId, req.params.languageId));
    this.createChapter = this._wrapWithUser((userId, req) => this.service.createChapter(userId, req.params.languageId, req.body), { successStatus: 201 });
    this.listLanguageVocabs = this._wrapWithUser((userId, req) => this.service.listLanguageVocabs(userId, req.params.languageId));
    this.searchVocabs = this._wrapWithUser((userId, req) => this.service.searchVocabs(userId, req.params.languageId, req.query));

    this.getChapter = this._wrapWithUser((userId, req) => this.service.getChapter(userId, req.params.chapterId));
    this.listChapterVocabs = this._wrapWithUser((userId, req) => this.service.listChapterVocabs(userId, req.params.chapterId));
    this.addVocabToChapter = this._wrapWithUser((userId, req) => this.service.addVocabToChapter(userId, req.params.chapterId, req.body), { successStatus: 201 });

    // Courses
    this.createCourse = this._wrapWithUser((userId, req) => this.service.createCourse(userId, req.body), { successStatus: 201 });
    this.getCourses = this._wrapWithUser((userId, req) => this.service.getCourses(userId, req.query));
    this.getCourse = this._wrapWithUser((userId, req) => this.service.getCourse(userId, req.params.courseId));
    this.getCourseByShareCode = this._wrapWithUser((userId, req) => this.service.getCourseByShareCode(userId, req.body.shareCode));
    this.updateCourse = this._wrapWithUser((userId, req) => this.service.updateCourse(userId, req.params.courseId, req.body));
    this.deleteCourse = this._wrapWithUser((userId, req) => this.service.deleteCourse(userId, req.params.courseId));
    
    // Lessons
    this.getLesson = this._wrapWithUser((userId, req) => this.service.getLesson(userId, req.params.lessonId));
    this.addLessonToCourse = this._wrapWithUser((userId, req) => this.service.addLessonToCourse(userId, req.params.courseId, req.body), { successStatus: 201 });
    this.updateLesson = this._wrapWithUser((userId, req) => this.service.updateLesson(userId, req.params.lessonId, req.body));
    this.deleteLesson = this._wrapWithUser((userId, req) => this.service.deleteLesson(userId, req.params.lessonId));
    
    // Enrollment
    this.enrollInCourse = this._wrapWithUser((userId, req) => this.service.enrollInCourse(userId, req.params.courseId), { successStatus: 201 });
    this.unenrollFromCourse = this._wrapWithUser((userId, req) => this.service.unenrollFromCourse(userId, req.params.courseId));
    this.getMyCourses = this._wrapWithUser((userId) => this.service.getMyCourses(userId));
    
    // Progress
    this.getCourseProgress = this._wrapWithUser((userId, req) => this.service.getCourseProgress(userId, req.params.courseId));
    this.updateLessonProgress = this._wrapWithUser((userId, req) => this.service.updateLessonProgress(userId, req.params.lessonId, req.body));
    
    // Grammar Exercises
    this.getExerciseTypes = this._wrapWithUser((userId) => this.service.getExerciseTypes());
    this.createGrammarExercise = this._wrapWithUser((userId, req) => this.service.createGrammarExercise(userId, req.params.lessonId, req.body), { successStatus: 201 });
    this.getGrammarExercisesForLesson = this._wrapWithUser((userId, req) => this.service.getGrammarExercisesForLesson(userId, req.params.lessonId));
    this.getGrammarExercise = this._wrapWithUser((userId, req) => this.service.getGrammarExercise(userId, req.params.exerciseId));
    this.checkGrammarExerciseAnswer = this._wrapWithUser((userId, req) => this.service.checkGrammarExerciseAnswer(userId, req.params.exerciseId, req.body.answer));
    this.getGrammarExerciseProgress = this._wrapWithUser((userId, req) => this.service.getGrammarExerciseProgress(userId, req.params.lessonId));
    this.updateGrammarExercise = this._wrapWithUser((userId, req) => this.service.updateGrammarExercise(userId, req.params.exerciseId, req.body));
    this.deleteGrammarExercise = this._wrapWithUser((userId, req) => this.service.deleteGrammarExercise(userId, req.params.exerciseId));
  }

  _wrapWithUser(fn, { successStatus = 200 } = {}) {
    return async (req, res) => {
      try {
        const hashedUserId = extractHashedUserId(req);
        if (!hashedUserId) {
          return res.status(400).json({ error: 'Missing user identifier' });
        }
        const result = await fn(hashedUserId, req, res);
        res.status(successStatus).json(result);
      } catch (error) {
        console.error('Controller error:', error);
        const status = error.status && typeof error.status === 'number' ? error.status : 500;
        res.status(status).json({ error: error.message || 'Internal error' });
      }
    };
  }
}

export default VocabController;


