File size: 3,205 Bytes
4bea261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { getLocalMovies } from '../../../lib/localDb.js';

// Cấu hình timeout cho fetch
async function fetchWithTimeout(resource, options = {}) {
  const { timeout = 8000 } = options;
  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeout);
  try {
    const response = await fetch(resource, {
      ...options,
      signal: controller.signal
    });
    return response;
  } finally {
    clearTimeout(id);
  }
}

export async function GET({ request }) {
  // Check quyền admin từ cookie auth_token
  const cookies = request.headers.get('cookie') || '';
  const hasToken = cookies.includes('auth_token=');
  if (!hasToken) {
    return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401 });
  }

  const url = new URL(request.url);
  const keyword = url.searchParams.get('keyword') || '';

  if (!keyword.trim()) {
    return new Response(JSON.stringify({ items: [], APP_DOMAIN_CDN_IMAGE: '' }), {
      headers: { 'Content-Type': 'application/json' }
    });
  }

  try {
    // 1. Gọi API tìm kiếm trực tuyến của KKPhim
    const kkRes = await fetchWithTimeout(
      `https://phimapi.com/v1/api/tim-kiem?keyword=${encodeURIComponent(keyword)}&limit=40`
    );
    if (!kkRes.ok) {
      throw new Error(`API KKPhim trả về HTTP ${kkRes.status}`);
    }

    const searchData = await kkRes.json();
    if (searchData.status !== 'success') {
      throw new Error(searchData.message || 'Lỗi API KKPhim');
    }

    const items = searchData.data?.items || [];
    const imageDomain = searchData.data?.APP_DOMAIN_CDN_IMAGE || 'https://phimimg.com';

    // 2. Load phim cục bộ để đối chiếu
    const localMovies = await getLocalMovies();

    // 3. Map kết quả đối chiếu
    const mappedItems = items.map(item => {
      const existing = localMovies[item.slug];
      
      let localEpCount = 0;
      if (existing && Array.isArray(existing.episodes)) {
        localEpCount = Math.max(...existing.episodes.map(s => s.server_data?.length || 0), 0);
      }

      return {
        name: item.name,
        origin_name: item.origin_name,
        slug: item.slug,
        type: item.type,
        thumb_url: item.thumb_url.startsWith('http') ? item.thumb_url : `${imageDomain}/${item.thumb_url}`,
        poster_url: item.poster_url.startsWith('http') ? item.poster_url : `${imageDomain}/${item.poster_url}`,
        year: item.year || 'N/A',
        episode_current: item.episode_current || 'N/A',
        exists: !!existing,
        local_episode_count: localEpCount,
        existing_status: existing ? (existing.movie.status || 'N/A') : null,
        existing_episodes: existing && Array.isArray(existing.episodes) 
          ? existing.episodes.flatMap(s => s.server_data?.map(ep => ep.name) || []) 
          : []
      };
    });

    return new Response(JSON.stringify({ 
      items: mappedItems, 
      APP_DOMAIN_CDN_IMAGE: imageDomain 
    }), {
      headers: { 'Content-Type': 'application/json' }
    });

  } catch (err) {
    return new Response(JSON.stringify({ error: err.message }), { 
      status: 500,
      headers: { 'Content-Type': 'application/json' }
    });
  }
}