import { useCallback } from "react";
import { useApiInterceptor } from "./useApiInterceptor";

type Option = {
  id?: number;
  value: string;
  [key: string]: any;
};

type Question = {
  id: number;
  title?: string;
  questionText: string;
  description?: string;
  score?: number;
  testId?: number;
  topic?: string;
  options: Record<string, string> | Option[];
  answer: string;
  isActive?: boolean;
  created_at?: string;
  updated_at?: string;
};

type Test = {
  id: number;
  name?: string;
  title?: string;
  passingScore?: number;
  passing_score?: number;
  questions: Question[];
  psychometricQuestionLibrary?: {
    questions: Question[];
  };
  description?: string;
  duration?: number;
  role?: string;
  isActive?: boolean;
};

type QuestionLibrary = {
  id: number;
  title: string;
  description?: string;
  subject?: string;
  role?: string;
  noOfQuestions?: number;
  created_at?: string;
  updated_at?: string;
};

type ExamPerformance = {
  id: number;
  candidateId: number;
  examId: number;
  examType: string;
  answerSet: Record<string, any>;
  score: string;
  status: "IN_PROGRESS" | "COMPLETED" | "NOT_STARTED";
  startTime: string;
  endTime?: string;
  created_at?: string;
  updated_at?: string;
};

type ResultData = {
  id: number;
  candidateId: number;
  examId: number;
  score: string;
  percentage?: number;
  status: string;
  startTime: string;
  endTime: string;
  answerSet: Record<string, any>;
  performance?: ExamPerformance;
  exam?: Test;
  candidate?: {
    id: number;
    user?: {
      id: number;
      name: string;
      email: string;
    };
  };
};

type CreateQuestionPayload = {
  psychometricQuestionLibraryId: number;
  questionText: string;
  options: Record<string, string>;
  answer: string;
  topic?: string;
  weights?: Record<string, number>;
  isActive?: boolean;
};

type CreateExamPayload = {
  psychometricQuestionLibraryId: number;
  title: string;
  description?: string;
  duration: number;
  role?: string;
  isActive?: boolean;
};

type StartExamPayload = {
  psychometricExamId: number;
};

type SubmitExamPayload = {
  performanceId: number;
  answers: Record<string, string | number>;
};

type ApiResponse<T> = {
  message: string;
  data: T;
  errors?: Array<{ message: string; [key: string]: any }>;
};

// ============ LOCAL STORAGE UTILITIES ============

type StoredExamData = {
  examId: number;
  examType: "skill" | "psychometric";
  performanceId?: number;
  answers: Record<string, any>;
  timestamp: number;
  userId?: number;
};

// Local storage keys
const SKILL_EXAM_STORAGE_KEY = "skill_exam_answers";
const PSYCHOMETRIC_EXAM_STORAGE_KEY = "psychometric_exam_answers";

// Save answers to localStorage
const saveExamAnswers = (
  examId: number,
  examType: "skill" | "psychometric",
  answers: Record<string, any>,
  performanceId?: number,
  userId?: number
) => {
  try {
    const storageKey =
      examType === "skill"
        ? SKILL_EXAM_STORAGE_KEY
        : PSYCHOMETRIC_EXAM_STORAGE_KEY;
    const data: StoredExamData = {
      examId,
      examType,
      performanceId,
      answers,
      timestamp: Date.now(),
      userId,
    };
    localStorage.setItem(storageKey, JSON.stringify(data));
    console.log(`Saved ${examType} exam answers to localStorage:`, data);
  } catch (error) {
    console.error("Failed to save exam answers to localStorage:", error);
  }
};

// Load answers from localStorage
const loadExamAnswers = (
  examId: number,
  examType: "skill" | "psychometric",
  userId?: number
): Record<string, any> | null => {
  try {
    const storageKey =
      examType === "skill"
        ? SKILL_EXAM_STORAGE_KEY
        : PSYCHOMETRIC_EXAM_STORAGE_KEY;
    const stored = localStorage.getItem(storageKey);

    if (!stored) return null;

    const data: StoredExamData = JSON.parse(stored);

    // Validate data - be more flexible for migration
    if (data.examType !== examType) {
      console.log("Stored data is for different exam type, clearing...");
      clearExamAnswers(examType);
      return null;
    }

    // Allow loading if examId doesn't match (for migration between testId and examId)
    if (data.examId !== examId) {
      console.log(
        `Stored examId (${data.examId}) doesn't match requested (${examId}), but allowing for migration`
      );
    }

    // Check if data is too old (24 hours)
    const age = Date.now() - data.timestamp;
    if (age > 24 * 60 * 60 * 1000) {
      console.log("Stored data is too old, clearing...");
      clearExamAnswers(examType);
      return null;
    }

    // Check if user matches (if provided)
    if (userId && data.userId && data.userId !== userId) {
      console.log("Stored data is for different user, clearing...");
      clearExamAnswers(examType);
      return null;
    }

    console.log(`Loaded ${examType} exam answers from localStorage:`, data);
    return data.answers;
  } catch (error) {
    console.error("Failed to load exam answers from localStorage:", error);
    return null;
  }
};

// Clear answers from localStorage
const clearExamAnswers = (examType: "skill" | "psychometric") => {
  try {
    const storageKey =
      examType === "skill"
        ? SKILL_EXAM_STORAGE_KEY
        : PSYCHOMETRIC_EXAM_STORAGE_KEY;
    localStorage.removeItem(storageKey);
    console.log(`Cleared ${examType} exam answers from localStorage`);
  } catch (error) {
    console.error("Failed to clear exam answers from localStorage:", error);
  }
};

// ============ HOOK IMPLEMENTATION ============
const usePsychometricApi = () => {
  const api = useApiInterceptor();

  // Helper to normalize response shapes: support { data: T } or { message, data: T }
  const extract = <T>(resp: any): T => {
    if (!resp) return resp;
    if (resp.data && resp.data.data !== undefined) return resp.data.data as T;
    if (resp.data !== undefined) return resp.data as T;
    return resp as T;
  };

  // --------- Question Library Methods ---------
  const getQuestionLibraries = useCallback(async (): Promise<
    QuestionLibrary[]
  > => {
    try {
      const resp = await api.get(
        `/account/psychometric-exam-question-libraries`
      );
      return extract<QuestionLibrary[]>(resp) || [];
    } catch (error) {
      console.error("Error fetching question libraries:", error);
      throw error;
    }
  }, [api]);

  const getQuestionLibrary = useCallback(
    async (libraryId: number): Promise<QuestionLibrary> => {
      try {
        const resp = await api.get(
          `/account/psychometric-exam-question-libraries/${libraryId}`
        );
        return extract<QuestionLibrary>(resp);
      } catch (error) {
        console.error("Error fetching question library:", error);
        throw error;
      }
    },
    [api]
  );

  const createQuestionLibrary = useCallback(
    async (payload: {
      title: string;
      description?: string;
      subject?: string;
      role?: string;
      noOfQuestions?: number;
    }): Promise<QuestionLibrary> => {
      try {
        const body: any = { ...payload };
        if ((payload as any).noOfQuestions !== undefined) {
          body.noOfQuestions = (payload as any).noOfQuestions;
        }
        const resp = await api.post(
          `/account/psychometric-exam-question-libraries`,
          body
        );

        const result = extract<QuestionLibrary>(resp);
        return result;
      } catch (error) {
        console.error("[API] Error creating question library:", error);
        throw error;
      }
    },
    [api]
  );

  const updateQuestionLibrary = useCallback(
    async (
      libraryId: number,
      payload: Partial<QuestionLibrary>
    ): Promise<QuestionLibrary> => {
      try {
        const resp = await api.put(
          `/account/psychometric-exam-question-libraries/${libraryId}`,
          payload
        );
        return extract<QuestionLibrary>(resp);
      } catch (error) {
        console.error("Error updating question library:", error);
        throw error;
      }
    },
    [api]
  );

  const deleteQuestionLibrary = useCallback(
    async (libraryId: number): Promise<void> => {
      try {
        await api.delete(
          `/account/psychometric-exam-question-libraries/${libraryId}`
        );
      } catch (error) {
        console.error("Error deleting question library:", error);
        throw error;
      }
    },
    [api]
  );

  // --------- Question Methods ---------

  // Normalize frontend payload keys (camelCase) to backend snake_case where needed
  const normalizeQuestionPayload = (payload: any) => {
    if (!payload) return payload;
    const out: any = { ...payload };
    // Handle both questionText and title fields
    if (payload.questionText) out.title = payload.questionText;
    if (payload.psychometricQuestionLibraryId) {
      out.psychometricQuestionLibraryId = payload.psychometricQuestionLibraryId;
    }
    if (payload.isActive !== undefined) {
      out.isActive = payload.isActive;
    }
    return out;
  };

  const getQuestion = useCallback(
    async (questionId: number): Promise<Question> => {
      try {
        const resp = await api.get(
          `/account/psychometric-exam-questions/${questionId}`
        );
        return extract<Question>(resp);
      } catch (error) {
        console.error("Error fetching question:", error);
        throw error;
      }
    },
    [api]
  );

  const getQuestions = useCallback(
    async (libraryId?: number): Promise<Question[]> => {
      try {
        const url = libraryId
          ? `/account/psychometric-exam-questions?psychometricQuestionLibraryId=${libraryId}`
          : "/account/psychometric-exam-questions";
        const resp = await api.get(url);
        const data = extract<any>(resp);
        // backend may return { questions: [...] } or array directly
        if (Array.isArray(data)) return data as Question[];
        if (data?.questions) return data.questions as Question[];
        return data || [];
      } catch (error) {
        console.error("Error fetching questions:", error);
        throw error;
      }
    },
    [api]
  );

  const createQuestion = useCallback(
    async (payload: CreateQuestionPayload | any): Promise<Question> => {
      try {
        const body = normalizeQuestionPayload(payload);
        const resp = await api.post(
          `/account/psychometric-exam-questions`,
          body
        );
        return extract<Question>(resp);
      } catch (error) {
        console.error("Error creating question:", error);
        throw error;
      }
    },
    [api]
  );

  const createMultipleQuestions = useCallback(
    async (payload: CreateQuestionPayload[] | any[]): Promise<Question[]> => {
      try {
        const body = (payload || []).map((p) => normalizeQuestionPayload(p));
        const resp = await api.post(
          `/account/psychometric-exam-questions`,
          body
        );
        const data = extract<any>(resp);
        if (Array.isArray(data)) return data as Question[];
        if (data?.questions) return data.questions as Question[];
        return data || [];
      } catch (error) {
        console.error("Error creating questions:", error);
        throw error;
      }
    },
    [api]
  );

  const updateQuestion = useCallback(
    async (
      questionId: number,
      payload: Partial<CreateQuestionPayload> | any
    ): Promise<Question> => {
      try {
        const body = normalizeQuestionPayload(payload);
        const resp = await api.put<ApiResponse<Question>>(
          `/account/psychometric-exam-questions/${questionId}`,
          body
        );
        return resp.data?.data;
      } catch (error) {
        console.error("Error updating question:", error);
        throw error;
      }
    },
    [api]
  );

  const deleteQuestion = useCallback(
    async (questionId: number): Promise<void> => {
      try {
        await api.delete(`/account/psychometric-exam-questions/${questionId}`);
      } catch (error) {
        console.error("Error deleting question:", error);
        throw error;
      }
    },
    [api]
  );

  // --------- Exam Methods ---------

  const getExams = useCallback(async (): Promise<Test[]> => {
    try {
      const resp = await api.get(`/account/psychometric-exams`);
      return extract<Test[]>(resp) || [];
    } catch (error) {
      console.error("Error fetching exams:", error);
      throw error;
    }
  }, [api]);

  const getTest = useCallback(
    async (testId: number): Promise<Test> => {
      try {
        const resp = await api.get(`/account/psychometric-exams/${testId}`);
        return extract<Test>(resp);
      } catch (error) {
        console.error("Error fetching test:", error);
        throw error;
      }
    },
    [api]
  );

  const createExam = useCallback(
    async (payload: CreateExamPayload): Promise<Test> => {
      try {
        const resp = await api.post(`/account/psychometric-exams`, payload);
        return extract<Test>(resp);
      } catch (error) {
        console.error("Error creating exam:", error);
        throw error;
      }
    },
    [api]
  );

  const updateExam = useCallback(
    async (
      examId: number,
      payload: Partial<CreateExamPayload>
    ): Promise<Test> => {
      try {
        const resp = await api.put(
          `/account/psychometric-exams/${examId}`,
          payload
        );
        return extract<Test>(resp);
      } catch (error) {
        console.error("Error updating exam:", error);
        throw error;
      }
    },
    [api]
  );

  const deleteExam = useCallback(
    async (examId: number): Promise<void> => {
      try {
        await api.delete(`/account/psychometric-exams/${examId}`);
      } catch (error) {
        console.error("Error deleting exam:", error);
        throw error;
      }
    },
    [api]
  );

  // --------- Exam Taking Methods ---------

  const startTest = useCallback(
    async (
      payload: StartExamPayload
    ): Promise<{
      exam: Test;
      performanceId: number;
    }> => {
      try {
        const resp = await api.post(
          `/account/psychometric-exams/start`,
          payload
        );
        return extract<any>(resp);
      } catch (error) {
        console.error("Error starting test:", error);
        throw error;
      }
    },
    [api]
  );

  const submitTest = useCallback(
    async (payload: SubmitExamPayload): Promise<ResultData> => {
      try {
        const resp = await api.post(
          `/account/psychometric-exams/submit`,
          payload
        );
        return extract<ResultData>(resp);
      } catch (error) {
        console.error("Error submitting test:", error);
        throw error;
      }
    },
    [api]
  );

  // --------- Result Methods ---------

  const getResult = useCallback(
    async (performanceId: number): Promise<ResultData> => {
      try {
        const resp = await api.get(
          `/account/psychometric-exams/results/${performanceId}`
        );
        return extract<ResultData>(resp);
      } catch (error) {
        console.error("Error fetching result:", error);
        throw error;
      }
    },
    [api]
  );

  const getResults = useCallback(
    async (candidateId: number): Promise<ResultData[]> => {
      try {
        console.log("candidate id (psycho api)>>>>>>", candidateId);
        const resp = await api.get(
          `/account/psychometric-exams/results/my-results/${candidateId}`
        );
        return extract<ResultData[]>(resp) || [];
      } catch (error) {
        console.error("Error fetching results:", error);
        throw error;
      }
    },
    [api]
  );

  // Return all methods
  return {
    // Question Library
    getQuestionLibraries,
    getQuestionLibrary,
    createQuestionLibrary,
    updateQuestionLibrary,
    deleteQuestionLibrary,

    // Questions
    getQuestions,
    getQuestion,
    createQuestion,
    createMultipleQuestions,
    updateQuestion,
    deleteQuestion,

    // Exams
    getExams,
    getTest,
    createExam,
    updateExam,
    deleteExam,

    // Test Taking
    startTest,
    submitTest,

    // Results
    getResult,
    getResults,

    // Local Storage Utilities
    saveExamAnswers,
    loadExamAnswers,
    clearExamAnswers,
  };
};

export type {
  Test,
  Question,
  Option,
  QuestionLibrary,
  ExamPerformance,
  ResultData,
  CreateQuestionPayload,
  CreateExamPayload,
  StartExamPayload,
  SubmitExamPayload,
  ApiResponse,
};

export { usePsychometricApi };
