import path from "path";
import fs from "fs";
import axios from "axios";
import { OAuth2Client } from "google-auth-library";
import { verifyIdToken } from "apple-signin-auth";
import { startSession } from "mongoose";
import { OtpModel } from "../../models/OtpModel";
import DeviceModel from "../../models/DevicesModel";

class GeneralHelper {
    async downloadAndSaveImage(imageUrl: string, destinationDir: string): Promise<string | null> {
        if (!imageUrl) return null;

        const fileName: string = `${crypto.randomUUID()}.jpg`;
        const filePath: string = path.join(destinationDir, fileName);

        try {
            if (!fs.existsSync(destinationDir)) {
                fs.mkdirSync(destinationDir, { recursive: true });
            }

            const response = await axios.get<fs.ReadStream>(imageUrl, { responseType: 'stream' });

            return await new Promise((resolve, reject) => {
                const writer = fs.createWriteStream(filePath);
                response.data.pipe(writer);

                writer.on('finish', () => resolve(fileName));
                writer.on('error', (error) => reject(`Error writing file: ${error.message}`));
            });
        } catch (error) {
            console.error('Error downloading or saving image:', (error as Error).message);
            return null;
        }
    }

    async verifyGoogleToken(token: string, platform: string | null) {
        try {

            let CLIENT_ID = platform == "android" ? process.env.GOOGLE_ANDROID_CLIENT_ID : process.env.GOOGLE_IOS_CLIENT_ID;

            let googleClient = new OAuth2Client(
                CLIENT_ID
            );
            const ticket = await googleClient.verifyIdToken({
                idToken: token,
                audience: CLIENT_ID,
            });

            const payload = ticket.getPayload();
            console.log("User Google", {
                email: payload?.email,
                name: payload?.name,
                picture: payload?.picture,
                providerId: payload?.sub,
            });
            return {
                email: payload?.email,
                name: payload?.name,
                picture: payload?.picture,
                providerId: payload?.sub,
            };
        } catch (error) {
            throw new Error("Invalid Google token");
        }
    };

    async verifyAppleToken(token: string) {
        try {
            const payload = await verifyIdToken(token, {
                audience: process.env.APPLE_CLIENT_ID,
                issuer: process.env.APPLE_URL,
            });

            return {
                email: payload.email,
                providerId: payload.sub,
                name: payload.email,
                picture: null,
            };
        } catch (error) {
            throw new Error("Invalid Apple token: " + error);
        }
    };

    async handleDeleteUser(userId: string) {
        const session = await startSession();
        session.startTransaction();
        try {
            await OtpModel.deleteMany({ userId: userId }, { session });
            await session.commitTransaction();
            console.log(`User ${userId} data deleted successfully.`);
        } catch (error) {
            await session.abortTransaction();
            console.error(`Failed to delete user ${userId}:`, error);
            throw error;
        } finally {
            await session.endSession();
        }
    }

    async unlinkUserDevices(userId: string): Promise<void> {
        if (!userId || typeof userId !== "string" || userId.trim() === "") {
            throw new Error("Invalid userId provided");
        }
        try {
            await DeviceModel.deleteMany({ userId });
        } catch (error: any) {
            throw new Error("Failed to unlink user devices");
        }
    }

}

export default GeneralHelper;