import type { NextApiRequest, NextApiResponse } from 'next'
import { readUserInfo } from '@/lib/firebase/firestore/user';
import { UserInfo } from '@/lib/utils/types';
import { getStorage, ref, getDownloadURL, getBytes, } from "firebase/storage";
import { columnMatchFilter, whereFilter } from '@/lib/api/filters';
import { gunzip, gunzipSync } from 'zlib';
import { storage } from '@/lib/firebase/initFirebase';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {

  // Request type must be POST
  if (req.method !== 'POST') {
    res.status(405).json({ error: 'Method Not Allowed' })
    return
  }

  // Get the file id directly from the URL
  const fileid = req.query.fileid as string;

  // Get the userUid from the request body
  const { userUid } = req.body;

  // Get the Bearertoken from the request headers
  const { authorization } = req.headers;
  const token = authorization?.split('Bearer ')[1];
  
  // Get the userInformation from the firestore database
  const _userRes = await readUserInfo(userUid);
  if (_userRes.error) {
    res.status(500).json({ error: _userRes.error })
    return
  }

  // Get the user information from the response
  const userInfo = _userRes.data as UserInfo;  // can cast because we know that .data is NOT undefined

  // Check if the user has the right to access the file
  // Check the documents id against the fileid
  const allIds = userInfo.documents.map(doc => doc.id);
  if (!allIds.includes(fileid)) {
    res.status(401).json({ error: 'File not found' })
    return
  }

  // Check if the user token is valid
  if (!userInfo.apiKey || userInfo.apiKey !== token) {
    res.status(401).json({ error: 'Unauthorized or wrong token' })
    return
  }

  // Now that everything is checked, we can perform the ACTION ----------------------------------------------

  // If the file is in cloud storage, we can get the file from there
  const pathReference = ref(storage, fileid + '.json');
  const obj = await getBytes(pathReference);

  const _obj = gunzipSync(obj).toString();

  // const _obj = Buffer.from(obj).toString();
  let json = JSON.parse(_obj);

  // If some filters are set by the user, we can now apply them
  const { columns } = req.body;
  const { filters } = req.body;

  // Apply column selection first
  if (columns) {
    json = columnMatchFilter(json, columns);
  }

  // Apply filters
  if (filters) {
    json = whereFilter(json, filters);
  }

  res.status(200).json({ data: json })
  return
}