import { google } from 'googleapis';
import { Readable } from 'stream';

const SCOPES = ['https://www.googleapis.com/auth/drive.file'];

export const getDriveService = () => {
    // 1. Try OAuth2 (Recommended for Personal Accounts to avoid 0 quota issue)
    if (process.env.DRIVE_CLIENT_ID && process.env.DRIVE_CLIENT_SECRET && process.env.DRIVE_REFRESH_TOKEN) {
        const oauth2Client = new google.auth.OAuth2(
            process.env.DRIVE_CLIENT_ID,
            process.env.DRIVE_CLIENT_SECRET
        );
        oauth2Client.setCredentials({
            refresh_token: process.env.DRIVE_REFRESH_TOKEN
        });
        return google.drive({ version: 'v3', auth: oauth2Client });
    }

    // 2. Fallback to Service Account (Requires Shared Drive for Workspace to avoid 0 quota)
    if (!process.env.FIREBASE_SERVICE_ACCOUNT_KEY) {
        throw new Error('Google Drive Auth: Neither OAuth2 nor Service Account key is provided.');
    }

    const credentials = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT_KEY);

    const auth = new google.auth.GoogleAuth({
        credentials,
        scopes: SCOPES,
    });

    return google.drive({ version: 'v3', auth });
};

export const uploadFileToDrive = async (
    file: Buffer,
    fileName: string,
    mimeType: string,
    folderId: string
) => {
    const drive = getDriveService();

    const fileMetadata = {
        name: fileName,
        parents: [folderId],
    };

    const media = {
        mimeType: mimeType,
        body: Readable.from(file),
    };

    try {
        const response = await drive.files.create({
            requestBody: fileMetadata,
            media: media,
            fields: 'id, name, webViewLink, webContentLink',
        });

        return response.data;
    } catch (error: any) {
        console.error('Error uploading file to Google Drive:', {
            message: error.message,
            code: error.code,
            errors: error.errors
        });
        throw error;
    }
};

export const findFolder = async (parentFolderId: string, folderName: string): Promise<string | null> => {
    const drive = getDriveService();
    try {
        const query = `mimeType='application/vnd.google-apps.folder' and '${parentFolderId}' in parents and name = '${folderName}' and trashed = false`;
        const res = await drive.files.list({
            q: query,
            fields: 'files(id, name)',
            spaces: 'drive',
        });
        const files = res.data.files;
        if (files && files.length > 0) {
            return files[0].id || null;
        }
        return null;
    } catch (error) {
        console.error('Error finding folder:', error);
        return null;
    }
};

export const createFolder = async (parentFolderId: string, folderName: string): Promise<string> => {
    const drive = getDriveService();
    const fileMetadata = {
        name: folderName,
        mimeType: 'application/vnd.google-apps.folder',
        parents: [parentFolderId],
    };
    try {
        const file = await drive.files.create({
            requestBody: fileMetadata,
            fields: 'id',
        });
        if (!file.data.id) throw new Error('Failed to create folder');
        return file.data.id;
    } catch (error) {
        console.error('Error creating folder:', error);
        throw error;
    }
}

export const deleteFile = async (fileId: string): Promise<void> => {
    const drive = getDriveService();
    try {
        await drive.files.delete({
            fileId: fileId,
        });
    } catch (error) {
        console.error('Error deleting file:', error);
        throw error;
    }
}

