import { useState } from 'react'

import { API_URL } from '../../config'
import { isConst, isObject } from '../../utils/types'
import { handleHTTPErrors } from '../../utils'

interface AuthData {
    email: string,
    password: string,
}

// interface LoginData extends AuthData { }

// interface SignUpData extends AuthData {
//     name: string,
//     surname: string
// }

type SignUpResponse = {
    Success: true
} | {
    Success: false,
    Message: string
}

const isSignUpResponse = (obj: unknown): obj is SignUpResponse => (
    isObject(obj, {
        'Success': isConst(true)
    }) ||
    isObject(obj, {
        'Success': isConst(false),
        'Message': 'string'
    })
)

interface LogInResponse {
    access_token: string,
    token_type: 'bearer'
}

const isLogInResponse = (obj: unknown): obj is LogInResponse => isObject(obj, {
    'access_token': 'string',
    'token_type': isConst('bearer')
})

function useAuth() {
    const [loading, setLoading] = useState(false)
    const [error, setError] = useState('')

    const doAuth = async (data: AuthData, newAccount: boolean) => {
        setLoading(true)

        if (newAccount) {
            try {
                const res = await fetch(API_URL + '/signup', {
                    method: 'POST',
                    body: JSON.stringify(data),
                    headers: {
                        'Content-Type': 'application/json'
                    }
                })

                handleHTTPErrors(res)

                const signupData: unknown = await res.json()

                if (!isSignUpResponse(signupData)) {
                    throw new Error('Malformed server response')
                }

                if (signupData.Success === false) {
                    throw new Error(signupData.Message)
                }

            } catch (err) {
                setError(err instanceof Error ? err.message : err as string)
                setLoading(false)
                return null
            }
        }

        try {
            const res = await fetch(API_URL + '/auth/token' + new URLSearchParams({
                username: data.email,
                password: data.password
            }).toString(), {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            })

            const logInData: unknown = await res.json()

            if (!isLogInResponse(logInData)) {
                throw new Error('Malformed server response')
            }

            const token = logInData.access_token

            setError('')
            setLoading(false)

            return token
        } catch (err) {
            setError(err instanceof Error ? err.message : err as string)
            setLoading(false)
            return null
        }
    }

    return { doAuth, loading, error }
}

export default useAuth
