/**
 * Hook for managing the assessment session state.
 */

import { useState, useCallback, useEffect } from 'react';
import type {
  AppView,
  DimensionDefinitions,
  QueryInfo,
  QueryWithIdeas,
  Rater,
  RaterProgress,
} from '../types';
import * as api from '../services/api';

interface AssessmentState {
  view: AppView;
  rater: Rater | null;
  queries: QueryInfo[];
  currentQueryIndex: number;
  currentQuery: QueryWithIdeas | null;
  currentIdeaIndex: number;
  progress: RaterProgress | null;
  dimensions: DimensionDefinitions | null;
  loading: boolean;
  error: string | null;
}

const initialState: AssessmentState = {
  view: 'login',
  rater: null,
  queries: [],
  currentQueryIndex: 0,
  currentQuery: null,
  currentIdeaIndex: 0,
  progress: null,
  dimensions: null,
  loading: false,
  error: null,
};

export function useAssessment() {
  const [state, setState] = useState<AssessmentState>(initialState);

  // Load dimension definitions on mount
  useEffect(() => {
    api.getDimensionDefinitions()
      .then((dimensions) => setState((s) => ({ ...s, dimensions })))
      .catch((err) => console.error('Failed to load dimensions:', err));
  }, []);

  // Login as a rater
  const login = useCallback(async (raterId: string, name?: string) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const rater = await api.createOrGetRater({ rater_id: raterId, name });
      const queries = await api.listQueries();
      const progress = await api.getRaterProgress(raterId);

      setState((s) => ({
        ...s,
        rater,
        queries,
        progress,
        view: 'instructions',
        loading: false,
      }));
    } catch (err) {
      setState((s) => ({
        ...s,
        error: err instanceof Error ? err.message : 'Login failed',
        loading: false,
      }));
    }
  }, []);

  // Start assessment (move from instructions to assessment)
  const startAssessment = useCallback(async () => {
    if (!state.rater || state.queries.length === 0) return;

    setState((s) => ({ ...s, loading: true }));
    try {
      // Find first query with unrated ideas
      let queryIndex = 0;
      let queryData: QueryWithIdeas | null = null;

      for (let i = 0; i < state.queries.length; i++) {
        const unrated = await api.getUnratedIdeas(state.queries[i].query_id, state.rater.rater_id);
        if (unrated.ideas.length > 0) {
          queryIndex = i;
          queryData = unrated;
          break;
        }
      }

      if (!queryData) {
        // All done
        setState((s) => ({
          ...s,
          view: 'completion',
          loading: false,
        }));
        return;
      }

      setState((s) => ({
        ...s,
        view: 'assessment',
        currentQueryIndex: queryIndex,
        currentQuery: queryData,
        currentIdeaIndex: 0,
        loading: false,
      }));
    } catch (err) {
      setState((s) => ({
        ...s,
        error: err instanceof Error ? err.message : 'Failed to start assessment',
        loading: false,
      }));
    }
  }, [state.rater, state.queries]);

  // Move to next idea
  const nextIdea = useCallback(async () => {
    if (!state.currentQuery || !state.rater) return;

    const nextIndex = state.currentIdeaIndex + 1;

    if (nextIndex < state.currentQuery.ideas.length) {
      // More ideas in current query
      setState((s) => ({ ...s, currentIdeaIndex: nextIndex }));
    } else {
      // Query complete, try to move to next query
      const nextQueryIndex = state.currentQueryIndex + 1;

      if (nextQueryIndex < state.queries.length) {
        setState((s) => ({ ...s, loading: true }));
        try {
          const unrated = await api.getUnratedIdeas(
            state.queries[nextQueryIndex].query_id,
            state.rater.rater_id
          );

          if (unrated.ideas.length > 0) {
            setState((s) => ({
              ...s,
              currentQueryIndex: nextQueryIndex,
              currentQuery: unrated,
              currentIdeaIndex: 0,
              loading: false,
            }));
          } else {
            // Try to find next query with unrated ideas
            for (let i = nextQueryIndex + 1; i < state.queries.length; i++) {
              const nextUnrated = await api.getUnratedIdeas(
                state.queries[i].query_id,
                state.rater.rater_id
              );
              if (nextUnrated.ideas.length > 0) {
                setState((s) => ({
                  ...s,
                  currentQueryIndex: i,
                  currentQuery: nextUnrated,
                  currentIdeaIndex: 0,
                  loading: false,
                }));
                return;
              }
            }
            // All queries complete
            setState((s) => ({
              ...s,
              view: 'completion',
              loading: false,
            }));
          }
        } catch (err) {
          setState((s) => ({
            ...s,
            error: err instanceof Error ? err.message : 'Failed to load next query',
            loading: false,
          }));
        }
      } else {
        // All queries complete
        setState((s) => ({ ...s, view: 'completion' }));
      }
    }

    // Refresh progress
    try {
      const progress = await api.getRaterProgress(state.rater.rater_id);
      setState((s) => ({ ...s, progress }));
    } catch (err) {
      console.error('Failed to refresh progress:', err);
    }
  }, [state.currentQuery, state.currentIdeaIndex, state.currentQueryIndex, state.queries, state.rater]);

  // Move to previous idea
  const prevIdea = useCallback(() => {
    if (state.currentIdeaIndex > 0) {
      setState((s) => ({ ...s, currentIdeaIndex: s.currentIdeaIndex - 1 }));
    }
  }, [state.currentIdeaIndex]);

  // Jump to a specific query
  const jumpToQuery = useCallback(async (queryIndex: number) => {
    if (!state.rater || queryIndex < 0 || queryIndex >= state.queries.length) return;

    setState((s) => ({ ...s, loading: true }));
    try {
      const queryData = await api.getQueryWithIdeas(state.queries[queryIndex].query_id);
      setState((s) => ({
        ...s,
        currentQueryIndex: queryIndex,
        currentQuery: queryData,
        currentIdeaIndex: 0,
        view: 'assessment',
        loading: false,
      }));
    } catch (err) {
      setState((s) => ({
        ...s,
        error: err instanceof Error ? err.message : 'Failed to load query',
        loading: false,
      }));
    }
  }, [state.rater, state.queries]);

  // Refresh progress
  const refreshProgress = useCallback(async () => {
    if (!state.rater) return;
    try {
      const progress = await api.getRaterProgress(state.rater.rater_id);
      setState((s) => ({ ...s, progress }));
    } catch (err) {
      console.error('Failed to refresh progress:', err);
    }
  }, [state.rater]);

  // Show definitions
  const showInstructions = useCallback(() => {
    setState((s) => ({ ...s, view: 'instructions' }));
  }, []);

  // Return to assessment
  const returnToAssessment = useCallback(() => {
    setState((s) => ({ ...s, view: 'assessment' }));
  }, []);

  // Logout
  const logout = useCallback(() => {
    setState(initialState);
  }, []);

  // Get current idea
  const currentIdea = state.currentQuery?.ideas[state.currentIdeaIndex] ?? null;

  return {
    ...state,
    currentIdea,
    login,
    startAssessment,
    nextIdea,
    prevIdea,
    jumpToQuery,
    refreshProgress,
    showInstructions,
    returnToAssessment,
    logout,
  };
}
