File size: 2,931 Bytes
d9a16d6
 
 
 
 
 
 
 
88452f7
d9a16d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5686111
d9a16d6
 
 
 
 
 
 
 
 
 
 
eb7f5ba
486eff6
 
5686111
 
 
 
 
 
 
d9a16d6
 
 
245c727
 
 
 
d9a16d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { useState, useCallback } from 'react';

const useCrossword = () => {
  const [puzzle, setPuzzle] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [topics, setTopics] = useState([]);

  const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || (import.meta.env.PROD ? '' : 'http://localhost:3000');

  const fetchTopics = useCallback(async () => {
    try {
      setLoading(true);
      const response = await fetch(`${API_BASE_URL}/api/topics`);
      if (!response.ok) throw new Error('Failed to fetch topics');
      const data = await response.json();
      setTopics(data);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [API_BASE_URL]);

  const generatePuzzle = useCallback(async (selectedTopics, difficulty = 'medium', useAI = false, customSentence = '', multiTheme = true, advancedParams = {}) => {
    try {
      setLoading(true);
      setError(null);
      
      const response = await fetch(`${API_BASE_URL}/api/generate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          topics: selectedTopics,
          difficulty,
          useAI,
          ...(customSentence && { customSentence }),
          multiTheme,
          ...(advancedParams.similarityTemperature !== undefined && { 
            similarityTemperature: advancedParams.similarityTemperature 
          }),
          ...(advancedParams.difficultyWeight !== undefined && { 
            difficultyWeight: advancedParams.difficultyWeight 
          })
        })
      });

      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(errorData.message || 'Failed to generate puzzle');
      }
      
      const puzzleData = await response.json();
      setPuzzle(puzzleData);
      return puzzleData;
    } catch (err) {
      setError(err.message);
      return null;
    } finally {
      setLoading(false);
    }
  }, [API_BASE_URL]);

  const validateAnswers = useCallback(async (userAnswers) => {
    try {
      const response = await fetch(`${API_BASE_URL}/api/validate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          puzzle: puzzle,
          answers: userAnswers
        })
      });

      if (!response.ok) throw new Error('Failed to validate answers');
      
      return await response.json();
    } catch (err) {
      setError(err.message);
      return null;
    }
  }, [API_BASE_URL, puzzle]);

  const resetPuzzle = useCallback(() => {
    setPuzzle(null);
    setError(null);
  }, []);

  return {
    puzzle,
    loading,
    error,
    topics,
    fetchTopics,
    generatePuzzle,
    validateAnswers,
    resetPuzzle
  };
};

export default useCrossword;