import { supabase } from '../../supabaseClient';
import { CCUser, convertToCCUser } from '../../services/auth/authService';
import { EmailCredentials } from '../../services/auth/authService';
import { formatEmailForDatabase } from '../graph/neoDBService';
import { RegistrationResponse } from '../../services/auth/authService';
import { storageService, StorageKeys } from './localStorageService';
import { logger } from '../../debugConfig';
import { provisionUser } from '../provisioningService';

const REGISTRATION_SERVICE = 'registration-service';

export class RegistrationService {
    private static instance: RegistrationService;

    private constructor() {}

    static getInstance(): RegistrationService {
        if (!RegistrationService.instance) {
            RegistrationService.instance = new RegistrationService();
        }
        return RegistrationService.instance;
    }

    async register(credentials: EmailCredentials, displayName: string): Promise<RegistrationResponse> {
        try {
            logger.debug(REGISTRATION_SERVICE, '🔄 Starting registration', { 
                email: credentials.email, 
                role: credentials.role,
                hasDisplayName: !!displayName 
            });

            // Generate username from email (or use another method)
            const username = formatEmailForDatabase(credentials.email);

            // 1. First sign up the user in auth
            const { data: authData, error: signUpError } = await supabase.auth.signUp({
                email: credentials.email,
                password: credentials.password,
                options: {
                    data: {
                        user_type: credentials.role,
                        username: username,
                        display_name: displayName
                    }
                }
            });

            if (signUpError) {
                logger.error(REGISTRATION_SERVICE, '❌ Supabase signup error', { error: signUpError });
                throw signUpError;
            }

            if (!authData.user) {
                logger.error(REGISTRATION_SERVICE, '❌ No user data after registration');
                throw new Error('No user data after registration');
            }

            const ccUser: CCUser = convertToCCUser(authData.user, authData.user.user_metadata);

            // 2. Update the profile with the correct user type
            const { error: updateError } = await supabase
                .from('profiles')
                .update({ 
                    user_type: credentials.role,
                    username: username,
                    display_name: displayName
                })
                .eq('id', authData.user.id)
                .select()
                .single();

            if (updateError) {
                logger.error(REGISTRATION_SERVICE, '❌ Failed to update profile', updateError);
                throw updateError;
            }

            storageService.set(StorageKeys.IS_NEW_REGISTRATION, true);

            let provisioningToken = authData.session?.access_token || null;
            if (!provisioningToken) {
                const { data: sessionData } = await supabase.auth.getSession();
                provisioningToken = sessionData.session?.access_token || null;
            }

            // 3. Create Neo4j nodes
            try {
                const provisioned = await provisionUser(ccUser.id, provisioningToken);
                if (provisioned) {
                    logger.info(REGISTRATION_SERVICE, '✅ Provisioning successful', {
                        userId: ccUser.id,
                        userDbName: provisioned.user_db_name,
                        workerDbName: provisioned.worker_db_name
                    });
                } else {
                    logger.warn(REGISTRATION_SERVICE, '⚠️ Provisioning skipped or pending', { userId: ccUser.id });
                }
            } catch (provisionError) {
                logger.warn(REGISTRATION_SERVICE, '⚠️ Provisioning error', {
                    userId: ccUser.id,
                    error: provisionError
                });
            }

            return {
                user: ccUser,
                accessToken: authData.session?.access_token || null,
                userRole: credentials.role,
                message: 'Registration successful'
            };
        } catch (error) {
            logger.error(REGISTRATION_SERVICE, '❌ Registration failed:', error);
            throw error;
        }
    }
}

export const registrationService = RegistrationService.getInstance();
