//NEEDS WORKS ON < PAST CODE >, SERVER SIDE RESIZE IMAGE
import {
  onCall,
  HttpsError,
  CallableRequest,
} from 'firebase-functions/v2/https';
import { logger } from 'firebase-functions/v2';

import { storage } from '../config';
import { toErrorWithMessage } from '../utils';
import { URL } from 'url';
import * as path from 'path';
interface HandleCkeditorImageData {
  temporaryUrl: string;
  targetBoard: string;
  targetDocId: string;
}

/**

 * @param {CallableRequest<HandleCkeditorImageData>} request - The request object containing auth and data.
 * @param {string} request.data.temporaryUrl - The full HTTPS URL of the temporary image.
 * @param {string} request.data.targetBoard - Identifier for the board/category (e.g., 'faq').
 * @param {string} request.data.targetDocId - The unique ID of the document being saved.
 *
 * @returns {Promise<{success: boolean, newUrl?: string}>} Result object.
 */

export const handleCkeditorImageV2 = onCall(
  { region: 'asia-northeast3' },

  // No options object - using defaults for region/memory etc.

  // Use CallableRequest with the specific data type
  async (request: CallableRequest<HandleCkeditorImageData>) => {
    // Use request.data to access client payload
    const { temporaryUrl, targetBoard, targetDocId } = request.data;

    logger.info('handleCkeditorImage: Function invoked.', {
      data: request.data,
      auth: request.auth?.uid,
    });

    // --- Input Validation ---
    if (!temporaryUrl || !targetBoard || !targetDocId) {
      logger.error('handleCkeditorImage: Missing required parameters.', {
        data: request.data,
      });
      throw new HttpsError( // Use imported HttpsError
        'invalid-argument',
        'Missing required parameters: temporaryUrl, targetBoard, targetDocId must be provided.',
      );
    }

    if (!request.auth) {
      logger.error('handleCkeditorImage: User is not authenticated.');
      throw new HttpsError(
        'unauthenticated',
        'The function must be called while authenticated.',
      );
    }
    const userId = request.auth.uid;
    logger.info(`handleCkeditorImage: Authenticated user: ${userId}`);

    try {
      // --- 1. Parse Temporary URL ---
      let parsedUrl: URL;
      let bucketName: string | undefined;
      let tempFilePath: string | undefined;

      try {
        parsedUrl = new URL(temporaryUrl);
        const pathSegments = parsedUrl.pathname.split('/');

        if (
          parsedUrl.hostname === 'firebasestorage.googleapis.com' &&
          pathSegments[3]
        ) {
          bucketName = pathSegments[3];
          tempFilePath = decodeURIComponent(
            pathSegments.slice(5).join('/'),
          ).split('?')[0];
        } else if (
          parsedUrl.hostname === 'storage.googleapis.com' &&
          pathSegments[1]
        ) {
          bucketName = pathSegments[1];
          tempFilePath = pathSegments.slice(2).join('/');
        } else {
          throw new Error(
            'Could not parse bucket/path from temporary URL hostname: ' +
              parsedUrl.hostname,
          );
        }

        if (!bucketName || !tempFilePath) {
          throw new Error('Failed to extract bucket or path from URL.');
        }
        logger.info(
          `handleCkeditorImage: Parsed URL: Bucket='${bucketName}', TempPath='${tempFilePath}'`,
        );
      } catch (urlError: unknown) {
        const errorMsg = toErrorWithMessage(urlError).message;
        logger.error('handleCkeditorImage: Invalid temporaryUrl format:', {
          temporaryUrl,
          errorMsg,
        });
        throw new HttpsError( // Use imported HttpsError
          'invalid-argument',
          `Invalid temporaryUrl format: ${errorMsg}`,
        );
      }

      // --- 2. Define Destination ---
      const tempFileName = path.basename(tempFilePath); // Extract filename
      // Construct the destination path
      const ckEditorFilePath = `boards/${targetBoard}/${targetDocId}/${tempFileName}`;
      logger.info(
        `handleCkeditorImage: Destination Path: '${ckEditorFilePath}'`,
      );

      // --- Get file references using imported storage ---
      const bucket = storage.bucket(bucketName); // Use storage from config
      const tempFile = bucket.file(tempFilePath);
      const destFile = bucket.file(ckEditorFilePath);

      // --- 3. Check if Temporary File Exists ---
      const [tempExists] = await tempFile.exists();
      if (!tempExists) {
        logger.error(
          `handleCkeditorImage: Temporary file does not exist: ${tempFilePath}`,
        );
        throw new HttpsError( // Use imported HttpsError
          'not-found',
          `Temporary file not found at ${tempFilePath}. It might have been already processed or deleted.`,
        );
      }

      // --- 4. Copy File ---
      logger.info(
        `handleCkeditorImage: Attempting to copy from '${tempFilePath}' to '${ckEditorFilePath}'`,
      );
      try {
        await tempFile.copy(destFile);
        logger.info('handleCkeditorImage: File copied successfully.');
      } catch (copyError: unknown) {
        const errorMsg = toErrorWithMessage(copyError).message;
        logger.error('handleCkeditorImage: Error copying file:', {
          source: tempFilePath,
          dest: ckEditorFilePath,
          errorMsg,
        });
        throw new HttpsError( // Use imported HttpsError
          'internal',
          `Failed to copy file: ${errorMsg}`,
        );
      }

      // --- 5. Make Destination File Publicly Readable ---
      // IMPORTANT: Still makes the file public. Ensure this is the desired behavior.
      try {
        await destFile.makePublic();
        logger.info(
          `handleCkeditorImage: Made '${ckEditorFilePath}' publicly readable.`,
        );
      } catch (publicError: unknown) {
        const errorMsg = toErrorWithMessage(publicError).message;
        logger.error(
          'handleCkeditorImage: Error making destination file public:',
          { dest: ckEditorFilePath, errorMsg },
        );
        throw new HttpsError( // Use imported HttpsError
          'internal',
          `File moved, but failed to make public: ${errorMsg}`,
        );
      }

      // --- 6. Get Public URL of Destination File ---
      const newUrl = destFile.publicUrl();
      logger.info(`handleCkeditorImage: New public URL: ${newUrl}`);

      // --- 7. Delete Temporary File ---
      logger.info(
        `handleCkeditorImage: Attempting to delete temporary file: '${tempFilePath}'`,
      );
      try {
        await tempFile.delete();
        logger.info(
          'handleCkeditorImage: Temporary file deleted successfully.',
        );
      } catch (deleteError: unknown) {
        // Log the error, but don't fail the whole operation.
        logger.error(
          'handleCkeditorImage: Error deleting temporary file (non-fatal):',
          {
            tempFile: tempFilePath,
            error: toErrorWithMessage(deleteError).message,
          },
        );
      }

      // --- 8. Return Success ---
      return { success: true, newUrl: newUrl };
    } catch (error: unknown) {
      logger.error('handleCkeditorImage: Unhandled error in main try block:', {
        error,
      });
      // Check if it's already an HttpsError, otherwise wrap it
      // Use HttpsError imported from v2
      if (error instanceof HttpsError) {
        throw error;
      } else {
        throw new HttpsError(
          'internal',
          toErrorWithMessage(error).message ||
            'An unexpected error occurred handling the image.',
        );
      }
    }
  }, // End of async handler
); // End of onCall
