import { onRequest } from 'firebase-functions/v2/https';
import { logger } from 'firebase-functions/v2';
import { getFirestore } from 'firebase-admin/firestore';
import { initializeApp, getApps } from 'firebase-admin/app';
import type { BoardItem, BoardAccessMode } from '../types/boardItem';

import { corsMiddlewareHandler, ALLOWED_COLLECTIONS } from '../config';
import {
  isValidBoardItem,
  verifySessionFromRequest,
  buildQueryWithAccessControl,
} from '../utils';

if (!getApps().length) {
  initializeApp();
}

const db = getFirestore();

export const fetchSingleItem = onRequest(
  { region: 'asia-northeast3' },
  async (request, response) => {
    return corsMiddlewareHandler(request, response, async () => {
      logger.info('fetchSingleItem: CORS-enabled function called');

      /* 1.Method guard ------------------------------------------------------------------ */
      if (request.method !== 'GET') {
        response.status(405).send({ message: 'Method Not Allowed' });
        return;
      }

      // 2. Auth (optional)
      let userRole = 0;
      let userId: string | null = null;

      const authUser = await verifySessionFromRequest(request);
      if (authUser) {
        userId = authUser.uid;
        userRole = authUser.role;
      }

      // 3. Query params
      const {
        collection = '',
        docId = '',
        access = 'public',
      } = request.query as Record<string, string>;

      if (!collection || !docId) {
        response.status(400).send({ message: 'Missing parameters' });
        return;
      }

      // ❶collection allow‑list
      if (
        !ALLOWED_COLLECTIONS.has(
          collection as unknown as typeof ALLOWED_COLLECTIONS extends Set<
            infer U
          >
            ? U
            : never,
        )
      ) {
        response.status(400).send({ message: 'Invalid collection' });
        return;
      }

      if (!['public', 'private', 'admin'].includes(access)) {
        response.status(400).send({ message: 'Bad access mode' });
        return;
      }
      const accessParam = (access ?? 'public') as BoardAccessMode;
      const effectiveAccess = userId ? accessParam : 'public'; // force public if anonymous

      try {
        // Build query with access control
        const query = buildQueryWithAccessControl(
          db.collection(collection),
          effectiveAccess,
          userId,
          userRole,
        ).where('__name__', '==', docId);

        const snap = await query.limit(1).get();

        if (snap.empty) {
          response
            .status(404)
            .send({ message: 'Item not found or access denied' });
          return;
        }

        const docSnap = snap.docs[0];
        const data = docSnap.data() as BoardItem;
        if (!isValidBoardItem(data)) {
          response.status(500).send({ message: 'Invalid item data' });
          return;
        }

        if (access === 'public') {
          response.set('Cache-Control', 'public,max-age=60');
        }

        response.status(200).send({ ...data, docId: docSnap.id });
        return;
      } catch (err) {
        logger.error('fetchSingleItem: Firestore error', err);
        response.status(500).send({ message: 'Internal Server Error' });
      }
    });
  },
);
