/**
 * Education Store
 * Zustand store for education module state management
 */

import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import type {
  CourseListItem,
  CourseDetail,
  CourseCategory,
  LessonDetail,
  UserEnrollment,
  EnrollmentWithCourse,
  CourseFilters,
  Quiz,
  QuizAttempt,
  QuizResult,
  GamificationProfile,
  LevelProgress,
  StreakStats,
  Achievement,
  LeaderboardEntry,
  UserLeaderboardPosition,
  GamificationSummary,
} from '../types/education.types';
import { educationService } from '../services/education.service';

// ============================================================================
// State Interface
// ============================================================================

interface EducationState {
  // Categories
  categories: CourseCategory[];
  loadingCategories: boolean;

  // Courses
  courses: CourseListItem[];
  totalCourses: number;
  currentPage: number;
  pageSize: number;
  loadingCourses: boolean;
  filters: CourseFilters;

  // Featured courses
  popularCourses: CourseListItem[];
  newCourses: CourseListItem[];
  loadingFeatured: boolean;

  // Current course/lesson
  currentCourse: CourseDetail | null;
  currentLesson: LessonDetail | null;
  loadingCourse: boolean;
  loadingLesson: boolean;

  // Enrollments
  myEnrollments: EnrollmentWithCourse[];
  loadingEnrollments: boolean;

  // Quiz
  currentQuiz: Quiz | null;
  currentAttempt: QuizAttempt | null;
  quizResult: QuizResult | null;
  loadingQuiz: boolean;
  submittingQuiz: boolean;

  // Gamification
  gamificationProfile: (GamificationProfile & { levelProgress: LevelProgress }) | null;
  streakStats: StreakStats | null;
  achievements: Achievement[];
  leaderboard: LeaderboardEntry[];
  myLeaderboardPosition: UserLeaderboardPosition | null;
  gamificationSummary: GamificationSummary | null;
  loadingGamification: boolean;

  // General
  error: string | null;

  // Actions
  fetchCategories: () => Promise<void>;
  fetchCourses: (filters?: CourseFilters) => Promise<void>;
  fetchFeaturedCourses: () => Promise<void>;
  fetchCourseBySlug: (slug: string) => Promise<void>;
  fetchCourseById: (courseId: string) => Promise<void>;
  fetchLesson: (lessonId: string) => Promise<void>;
  fetchMyEnrollments: () => Promise<void>;
  enrollInCourse: (courseId: string) => Promise<void>;
  updateLessonProgress: (lessonId: string, data: { videoWatchedSeconds?: number; videoCompleted?: boolean }) => Promise<void>;
  markLessonComplete: (lessonId: string) => Promise<void>;

  // Quiz actions
  fetchQuiz: (lessonId: string) => Promise<void>;
  startQuizAttempt: (quizId: string, enrollmentId?: string) => Promise<void>;
  submitQuiz: (attemptId: string, answers: { questionId: string; answer: string | string[] }[]) => Promise<void>;

  // Gamification actions
  fetchGamificationProfile: () => Promise<void>;
  fetchStreakStats: () => Promise<void>;
  recordDailyActivity: () => Promise<void>;
  fetchAchievements: () => Promise<void>;
  fetchLeaderboard: (period?: 'all_time' | 'month' | 'week', limit?: number) => Promise<void>;
  fetchMyLeaderboardPosition: (period?: 'all_time' | 'month' | 'week') => Promise<void>;
  fetchGamificationSummary: () => Promise<void>;

  // Utility
  setFilters: (filters: CourseFilters) => void;
  clearError: () => void;
  resetCurrentCourse: () => void;
  resetCurrentLesson: () => void;
  resetQuizState: () => void;
}

// ============================================================================
// Initial State
// ============================================================================

const initialState = {
  // Categories
  categories: [],
  loadingCategories: false,

  // Courses
  courses: [],
  totalCourses: 0,
  currentPage: 1,
  pageSize: 12,
  loadingCourses: false,
  filters: {},

  // Featured
  popularCourses: [],
  newCourses: [],
  loadingFeatured: false,

  // Current course/lesson
  currentCourse: null,
  currentLesson: null,
  loadingCourse: false,
  loadingLesson: false,

  // Enrollments
  myEnrollments: [],
  loadingEnrollments: false,

  // Quiz
  currentQuiz: null,
  currentAttempt: null,
  quizResult: null,
  loadingQuiz: false,
  submittingQuiz: false,

  // Gamification
  gamificationProfile: null,
  streakStats: null,
  achievements: [],
  leaderboard: [],
  myLeaderboardPosition: null,
  gamificationSummary: null,
  loadingGamification: false,

  // General
  error: null,
};

// ============================================================================
// Store
// ============================================================================

export const useEducationStore = create<EducationState>()(
  devtools(
    (set, get) => ({
      ...initialState,

      // ========================================================================
      // Category Actions
      // ========================================================================

      fetchCategories: async () => {
        set({ loadingCategories: true, error: null });

        try {
          const categories = await educationService.getCategories();
          set({ categories, loadingCategories: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch categories';
          set({ error: errorMessage, loadingCategories: false });
          console.error('Error fetching categories:', error);
        }
      },

      // ========================================================================
      // Course Actions
      // ========================================================================

      fetchCourses: async (filters?: CourseFilters) => {
        const state = get();
        const mergedFilters = { ...state.filters, ...filters };

        set({ loadingCourses: true, error: null, filters: mergedFilters });

        try {
          const result = await educationService.getCourses(mergedFilters);
          set({
            courses: result.data,
            totalCourses: result.total,
            currentPage: result.page,
            pageSize: result.pageSize,
            loadingCourses: false,
          });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch courses';
          set({ error: errorMessage, loadingCourses: false, courses: [] });
          console.error('Error fetching courses:', error);
        }
      },

      fetchFeaturedCourses: async () => {
        set({ loadingFeatured: true, error: null });

        try {
          const [popular, newList] = await Promise.all([
            educationService.getPopularCourses(6),
            educationService.getNewCourses(6),
          ]);
          set({ popularCourses: popular, newCourses: newList, loadingFeatured: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch featured courses';
          set({ error: errorMessage, loadingFeatured: false });
          console.error('Error fetching featured courses:', error);
        }
      },

      fetchCourseBySlug: async (slug: string) => {
        set({ loadingCourse: true, error: null, currentCourse: null });

        try {
          const course = await educationService.getCourseBySlug(slug);
          set({ currentCourse: course, loadingCourse: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch course';
          set({ error: errorMessage, loadingCourse: false });
          console.error('Error fetching course:', error);
        }
      },

      fetchCourseById: async (courseId: string) => {
        set({ loadingCourse: true, error: null, currentCourse: null });

        try {
          const course = await educationService.getCourseById(courseId);
          set({ currentCourse: course, loadingCourse: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch course';
          set({ error: errorMessage, loadingCourse: false });
          console.error('Error fetching course:', error);
        }
      },

      // ========================================================================
      // Lesson Actions
      // ========================================================================

      fetchLesson: async (lessonId: string) => {
        set({ loadingLesson: true, error: null, currentLesson: null });

        try {
          const lesson = await educationService.getLessonById(lessonId);
          set({ currentLesson: lesson, loadingLesson: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch lesson';
          set({ error: errorMessage, loadingLesson: false });
          console.error('Error fetching lesson:', error);
        }
      },

      updateLessonProgress: async (lessonId: string, data) => {
        try {
          await educationService.updateLessonProgress(lessonId, data);
        } catch (error) {
          console.error('Error updating lesson progress:', error);
        }
      },

      markLessonComplete: async (lessonId: string) => {
        try {
          const result = await educationService.markLessonComplete(lessonId);

          // Update current lesson if it matches
          const state = get();
          if (state.currentLesson?.id === lessonId) {
            set({
              currentLesson: {
                ...state.currentLesson,
                isCompleted: true,
                userProgress: state.currentLesson.userProgress
                  ? { ...state.currentLesson.userProgress, isCompleted: true }
                  : undefined,
              },
            });
          }

          // Refresh gamification if XP was awarded
          if (result.xpAwarded > 0) {
            get().fetchGamificationProfile();
          }
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to complete lesson';
          set({ error: errorMessage });
          console.error('Error completing lesson:', error);
        }
      },

      // ========================================================================
      // Enrollment Actions
      // ========================================================================

      fetchMyEnrollments: async () => {
        set({ loadingEnrollments: true, error: null });

        try {
          const enrollments = await educationService.getMyEnrollments();
          set({ myEnrollments: enrollments, loadingEnrollments: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch enrollments';
          set({ error: errorMessage, loadingEnrollments: false, myEnrollments: [] });
          console.error('Error fetching enrollments:', error);
        }
      },

      enrollInCourse: async (courseId: string) => {
        set({ error: null });

        try {
          await educationService.enrollInCourse(courseId);

          // Refresh current course to get enrollment status
          const state = get();
          if (state.currentCourse?.id === courseId) {
            get().fetchCourseById(courseId);
          }

          // Refresh enrollments list
          get().fetchMyEnrollments();
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to enroll in course';
          set({ error: errorMessage });
          console.error('Error enrolling in course:', error);
          throw error;
        }
      },

      // ========================================================================
      // Quiz Actions
      // ========================================================================

      fetchQuiz: async (lessonId: string) => {
        set({ loadingQuiz: true, error: null, currentQuiz: null });

        try {
          const quiz = await educationService.getQuizByLessonId(lessonId);
          set({ currentQuiz: quiz, loadingQuiz: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch quiz';
          set({ error: errorMessage, loadingQuiz: false });
          console.error('Error fetching quiz:', error);
        }
      },

      startQuizAttempt: async (quizId: string, enrollmentId?: string) => {
        set({ loadingQuiz: true, error: null, currentAttempt: null, quizResult: null });

        try {
          const result = await educationService.startQuizAttempt(quizId, enrollmentId);
          set({
            currentQuiz: result.quiz,
            currentAttempt: {
              id: result.attemptId,
              quizId,
              userId: '',
              score: 0,
              passed: false,
              answers: [],
              startedAt: result.startedAt,
            },
            loadingQuiz: false,
          });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to start quiz';
          set({ error: errorMessage, loadingQuiz: false });
          console.error('Error starting quiz:', error);
          throw error;
        }
      },

      submitQuiz: async (attemptId: string, answers) => {
        set({ submittingQuiz: true, error: null });

        try {
          const result = await educationService.submitQuizAttempt(attemptId, answers);
          set({
            quizResult: result,
            submittingQuiz: false,
          });

          // Refresh gamification if quiz was passed
          if (result.passed) {
            get().fetchGamificationProfile();
          }
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to submit quiz';
          set({ error: errorMessage, submittingQuiz: false });
          console.error('Error submitting quiz:', error);
          throw error;
        }
      },

      // ========================================================================
      // Gamification Actions
      // ========================================================================

      fetchGamificationProfile: async () => {
        set({ loadingGamification: true, error: null });

        try {
          const profile = await educationService.getGamificationProfile();
          set({ gamificationProfile: profile, loadingGamification: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch gamification profile';
          set({ error: errorMessage, loadingGamification: false });
          console.error('Error fetching gamification profile:', error);
        }
      },

      fetchStreakStats: async () => {
        try {
          const stats = await educationService.getStreakStats();
          set({ streakStats: stats });
        } catch (error) {
          console.error('Error fetching streak stats:', error);
        }
      },

      recordDailyActivity: async () => {
        try {
          await educationService.recordDailyActivity();
          // Refresh streak stats and gamification
          get().fetchStreakStats();
          get().fetchGamificationProfile();
        } catch (error) {
          console.error('Error recording daily activity:', error);
        }
      },

      fetchAchievements: async () => {
        try {
          const achievements = await educationService.getMyAchievements();
          set({ achievements });
        } catch (error) {
          console.error('Error fetching achievements:', error);
        }
      },

      fetchLeaderboard: async (period = 'all_time', limit = 100) => {
        try {
          const leaderboard = await educationService.getLeaderboard(period, limit);
          set({ leaderboard });
        } catch (error) {
          console.error('Error fetching leaderboard:', error);
        }
      },

      fetchMyLeaderboardPosition: async (period = 'all_time') => {
        try {
          const position = await educationService.getMyLeaderboardPosition(period);
          set({ myLeaderboardPosition: position });
        } catch (error) {
          console.error('Error fetching leaderboard position:', error);
        }
      },

      fetchGamificationSummary: async () => {
        set({ loadingGamification: true, error: null });

        try {
          const summary = await educationService.getGamificationSummary();
          set({ gamificationSummary: summary, loadingGamification: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch gamification summary';
          set({ error: errorMessage, loadingGamification: false });
          console.error('Error fetching gamification summary:', error);
        }
      },

      // ========================================================================
      // Utility Actions
      // ========================================================================

      setFilters: (filters: CourseFilters) => {
        set({ filters });
      },

      clearError: () => {
        set({ error: null });
      },

      resetCurrentCourse: () => {
        set({ currentCourse: null, loadingCourse: false });
      },

      resetCurrentLesson: () => {
        set({ currentLesson: null, loadingLesson: false });
      },

      resetQuizState: () => {
        set({
          currentQuiz: null,
          currentAttempt: null,
          quizResult: null,
          loadingQuiz: false,
          submittingQuiz: false,
        });
      },
    }),
    {
      name: 'education-store',
    }
  )
);

// ============================================================================
// Selectors
// ============================================================================

export const useCategories = () => useEducationStore((state) => state.categories);
export const useCourses = () => useEducationStore((state) => state.courses);
export const usePopularCourses = () => useEducationStore((state) => state.popularCourses);
export const useNewCourses = () => useEducationStore((state) => state.newCourses);
export const useCurrentCourse = () => useEducationStore((state) => state.currentCourse);
export const useCurrentLesson = () => useEducationStore((state) => state.currentLesson);
export const useMyEnrollments = () => useEducationStore((state) => state.myEnrollments);
export const useCurrentQuiz = () => useEducationStore((state) => state.currentQuiz);
export const useQuizResult = () => useEducationStore((state) => state.quizResult);
export const useGamificationProfile = () => useEducationStore((state) => state.gamificationProfile);
export const useStreakStats = () => useEducationStore((state) => state.streakStats);
export const useAchievements = () => useEducationStore((state) => state.achievements);
export const useLeaderboard = () => useEducationStore((state) => state.leaderboard);
export const useGamificationSummary = () => useEducationStore((state) => state.gamificationSummary);
export const useEducationError = () => useEducationStore((state) => state.error);
export const useLoadingCourses = () => useEducationStore((state) => state.loadingCourses);
export const useLoadingGamification = () => useEducationStore((state) => state.loadingGamification);

export default useEducationStore;
