File size: 6,390 Bytes
e557560
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
const axios = require('axios');
const Media = require('../models/Media');

// 1. GET TRENDING (Lazy Sync: Fetch TMDB -> Save DB -> Return)
exports.getTrending = async (req, res) => {
  try {
    // Fetch from TMDB
    const response = await axios.get(`https://api.themoviedb.org/3/trending/all/day`, {
      params: { 
        api_key: process.env.TMDB_KEY,
        region: 'IN' 
      }
    });

    const trendingItems = [];

    // Process results
    for (const item of response.data.results) {
      // Skip incomplete data or people
      if (item.media_type === 'person') continue;

      const releaseDate = item.release_date || item.first_air_date;
      const tmdbId = item.id.toString();

      // Prepare object for DB
      const mediaData = {
        tmdbId: tmdbId,
        title: item.title || item.name,
        type: item.media_type,
        posterPath: item.poster_path,
        backdropPath: item.backdrop_path,
        releaseDate: releaseDate ? new Date(releaseDate) : null,
        overview: item.overview,
        brutaleStats: {popularity : item.popularity, avgRating: item.vote_average, voteCount: item.vote_count},
      };

      // Upsert into DB (Update if exists, Insert if new)
      const updatedMedia = await Media.findOneAndUpdate(
        { tmdbId: tmdbId },
        mediaData,
        { upsert: true, new: true, setDefaultsOnInsert: true }
      );

      trendingItems.push(updatedMedia);
    }

    res.json(trendingItems);

  } catch (error) {
    console.error("Trending Error:", error.message);
    res.status(500).json({ error: 'Failed to fetch trending content' });
  }
};

exports.getPopular = async (req, res) => {
  try {
    const page = req.query.page || 1;

    // Fetch from TMDB
    const response = await axios.get(`https://api.themoviedb.org/3/movie/popular`, {
      params: { 
        api_key: process.env.TMDB_KEY,
        page,
        region: "IN"
      }
    });

    const popularItems = [];

    for (const item of response.data.results) {
      const tmdbId = item.id.toString();

      const mediaData = {
        tmdbId: tmdbId,
        title: item.title,
        type: 'movie',
        posterPath: item.poster_path,
        backdropPath: item.backdrop_path,
        releaseDate: item.release_date ? new Date(item.release_date) : null,
        overview: item.overview,
        brutaleStats: {
          popularity: item.popularity,
          avgRating: item.vote_average?.toFixed(1) || "0.0",
          voteCount: item.vote_count
        }
      };

      // Upsert into DB (Insert if new, update if existing)
      const updatedMedia = await Media.findOneAndUpdate(
        { tmdbId: tmdbId },
        mediaData,
        { upsert: true, new: true, setDefaultsOnInsert: true }
      );

      popularItems.push(updatedMedia);
    }

    res.json(popularItems);

  } catch (error) {
    console.error("Popular Error:", error.message);
    res.status(500).json({ error: "Failed to fetch popular movies" });
  }
};

// 2. GET DETAILS
exports.getMediaDetails = async (req, res) => {
  try {
    const { id } = req.params; // This is the TMDB ID passed from URL

    // Try finding in DB first
    let media = await Media.findOne({ tmdbId: id });

    // If not in DB, fetch from TMDB and save
    if (!media) {
      // We need to know if it's a movie or tv show. 
      // For this simplified version, we might need to try both or rely on the query param.
      // BUT, usually the user clicks from the homepage where we already saved it.
      // Let's try fetching as movie first, then TV as fallback.
      try {
        const tmdbRes = await axios.get(`https://api.themoviedb.org/3/movie/${id}`, {
          params: { api_key: process.env.TMDB_KEY }
        });
        const item = tmdbRes.data;
        media = await Media.create({
          tmdbId: item.id.toString(),
          title: item.title,
          type: 'movie',
          posterPath: item.poster_path,
          backdropPath: item.backdrop_path,
          releaseDate: item.release_date,
          overview: item.overview
        });
      } catch (err) {
        // Try TV
        const tmdbResTv = await axios.get(`https://api.themoviedb.org/3/tv/${id}`, {
          params: { api_key: process.env.TMDB_KEY }
        });
        const item = tmdbResTv.data;
        media = await Media.create({
          tmdbId: item.id.toString(),
          title: item.name,
          type: 'tv',
          posterPath: item.poster_path,
          backdropPath: item.backdrop_path,
          releaseDate: item.first_air_date,
          overview: item.overview
        });
      }
    }

    if (!media) return res.status(404).json({ error: 'Media not found' });
    res.json(media);

  } catch (error) {
    console.error("Details Error:", error.message);
    res.status(404).json({ error: 'Media not found on TMDB or DB' });
  }
};

// 3. SEARCH (Hybrid)
exports.searchMedia = async (req, res) => {
  const query = req.query.q;
  if (!query) return res.json([]);

  try {
    // Search DB (using text index created in Schema)
    // Note: Ensure you created the index in MongoDB Atlas or via Schema: MediaSchema.index({ title: 'text' });
    let results = await Media.find(
      { $text: { $search: query } },
      { score: { $meta: "textScore" } }
    ).sort({ score: { $meta: "textScore" } }).limit(10);

    // If few results, fetch TMDB
    if (results.length < 5) {
      const tmdbRes = await axios.get(`https://api.themoviedb.org/3/search/multi`, {
        params: { api_key: process.env.TMDB_KEY, query: query }
      });

      const tmdbItems = tmdbRes.data.results
        .filter(item => (item.media_type === 'movie' || item.media_type === 'tv') && item.poster_path)
        .map(item => ({
          tmdbId: item.id.toString(),
          title: item.title || item.name,
          posterPath: item.poster_path,
          type: item.media_type,
          releaseDate: item.release_date || item.first_air_date,
          // Temporary object structure for frontend
          brutaleStats: { avgRating: 0 }
        }));
      
      // Merge results (prevent duplicates)
      const existingIds = new Set(results.map(r => r.tmdbId));
      const newItems = tmdbItems.filter(i => !existingIds.has(i.tmdbId));
      results = [...results, ...newItems];
    }

    res.json(results);
  } catch (error) {
    res.status(500).json({ error: 'Search failed' });
  }
};