import axios from 'axios'
import * as qs from 'querystring'
import { Injectable } from '@nestjs/common'
import { TokenService } from './token.service'

@Injectable()
export class QuickBooksService {
	constructor(private readonly tokenService: TokenService) {}

	async getAccessToken({ type = 'refresh', code }: { type: 'refresh' | 'authCode'; code?: any }): Promise<string> {
		// Try to get existing token from database
		const existingToken = await this.tokenService.getLatestToken('quickbooks');
		
		if (existingToken?.accessToken && type === 'refresh') {
			// Check if token is still valid (you might want to add expiry check logic here)
            if (existingToken.expiresAt && new Date() < existingToken.expiresAt) {
                return existingToken.accessToken;
            }
		}

		if (type === 'refresh' && !existingToken?.refreshToken) {
			throw new Error('No QuickBooks refresh token available. Please authenticate manually.')
		}

		try {
			console.log('Refreshing QuickBooks access token...')
            const quickbooks_credentials = Buffer.from(`${process.env.QUICKBOOKS_CLIENT_ID}:${process.env.QUICKBOOKS_CLIENT_SECRET}`).toString('base64')
            let params = {}
            if (type === 'refresh') {
                params = {
                    grant_type: 'refresh_token',
                    refresh_token: existingToken?.refreshToken || '',
                }
            } else {
                params = {
                    grant_type: 'authorization_code',
                    code: code,
                    redirect_uri: process.env.QUICKBOOKS_REDIRECT_URI
                }
            }

			const tokenResponse = await axios.post(
				'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer',
				qs.stringify(params),
				{
					headers: {
						'Content-Type': 'application/x-www-form-urlencoded',
						'Accept': 'application/json',
						Authorization: `Basic ${quickbooks_credentials}`,
					},
				},
			)

			// Calculate expiry date if available in the response
			let expiresAt: Date | undefined = undefined;
			if (tokenResponse.data.expires_in) {
				expiresAt = new Date();
				expiresAt.setSeconds(expiresAt.getSeconds() + tokenResponse.data.expires_in);
			}

			// Save tokens to database
			if (existingToken) {
				await this.tokenService.updateToken(
					existingToken.id,
					tokenResponse.data.access_token,
					tokenResponse.data.refresh_token,
					expiresAt
				);
			} else {
				await this.tokenService.saveToken(
					'quickbooks',
					tokenResponse.data.access_token,
					tokenResponse.data.refresh_token,
					expiresAt
				);
			}

			console.log('New access token obtained and saved successfully.')
			return tokenResponse.data.access_token;
		} catch (error) {
			console.error('Error refreshing QuickBooks token:', error.response?.data || error.message)
			throw new Error('Failed to refresh QuickBooks access token.')
		}
	}

    oAuth() {
        return `https://appcenter.intuit.com/app/connect/oauth2?client_id=${process.env.QUICKBOOKS_CLIENT_ID}&scope=com.intuit.quickbooks.accounting&redirect_uri=${process.env.QUICKBOOKS_REDIRECT_URI}&response_type=code&state=PlaygroundAuth`   
    }
}
