import { format } from 'date-fns'
import BaseRefreshTokenApiService from './BaseRefreshTokenApiService'
import globalData from '../others/GlobalData'
import { UpdateUserReqM, ChangePasswordReqM, AddUserBusinessReqM, AddUserAddressReqM,
    AddUserTimeSheetStandartReqM, AddUserTimeSheetWeeklyReqM, AddOffPeriodReqM, NotificationReqM,
    AddUserTimeSheetMonthlyReqM, SaveLanguageKeyReqM, } from '../models/requestModels'
import { CurrentUserResM, GetAllUserAddressResM, GetUserTimeSheetesByAddressUidResM,
    GetUserBusinessResM, GetWeekSheduleResM, GetDaySheduleResM, GetNewAndAcceptedSheduleResM,
    GetAvailableTimesByAddressUidAndDateResM, GetAllOffPeriodsResM, } from '../models/responceModels'


type MyRequestInit = {
    headers?: HeadersInit,
    body?: any,
}


export default class UserApiService extends BaseRefreshTokenApiService
{
    defaultHeaders = {
        'Content-Type': 'application/json',
        'Accept-Language': this.globalData.getCurrLangKey(),
    }

    getCurrentUser(): Promise<CurrentUserResM>
    {
        let uri = this.coreApiUri + '/api/users/current'

        return this.get(uri)
    }

    getUserBusiness(): Promise<GetUserBusinessResM>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.userbusinessdetailed+json',
        }

        let uri = this.coreApiUri + `/api/users/${globalData.getCurrentUser().uid}/userBusinesses/default`

        return this.get(uri, { headers, })
    }

    updateUser(data: UpdateUserReqM): Promise<any>
    {
        let uri = this.coreApiUri + '/api/users'

        return this.put(uri, { body: data })
    }

    setNotificationData(data: NotificationReqM): Promise<any>
    {
        let uri = this.coreApiUri + '/api/users/saveToken'

        return this.post(uri, { body: data })
    }

    getCurrentUserProfileAbout(): Promise<String>
    {
        let uri = this.coreApiUri + '/api/users/profileAbout'

        return this.get(uri)
    }

    updateCurrentUserProfileAbout(data: { data: String }): Promise<any>
    {
        let uri = this.coreApiUri + '/api/users/profileAbout'

        return this.post(uri, { body: data })
    }

    updateUserPicture(data: { data: String }): Promise<any>
    {
        let uri = this.coreApiUri + '/api/users/profilePicture'

        return this.post(uri, { body: data })
    }

    logOut(): Promise<any>
    {
        let uri = this.coreApiUri + '/api/users/logout'

        return this.get(uri)
    }

    addUserBusiness(data: AddUserBusinessReqM): Promise<any>
    {
        let uri = this.coreApiUri + `/api/users/${globalData.getCurrentUser().uid}/userBusinesses`

        return this.post(uri, { body: data })
    }

    updateUserBusiness(data: AddUserBusinessReqM): Promise<any>
    {
        let uri = this.coreApiUri + `/api/users/${globalData.getCurrentUser().uid}/userBusinesses/${data.uid}`

        return this.put(uri, { body: data })
    }

    addUserAddressWithCreateObject(data: AddUserAddressReqM): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.useraddresswithobjectname+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses`

        return this.post(uri, { body: data, headers })
    }

    addUserAddress(data: AddUserAddressReqM): Promise<any>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses`

        return this.post(uri, { body: data })
    }

    updateUserAddress(data: AddUserAddressReqM): Promise<any>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.uid}`

        return this.put(uri, { body: data })
    }

    updateUserAddressWithCreateObject(data: AddUserAddressReqM): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.useraddresswithobjectname+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.uid}`

        return this.put(uri, { body: data, headers })
    }

    removeUserAddressByUid(addressUid: String): Promise<any>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${addressUid}`

        return this.delete(uri)
    }

    getAllUserAddresses(): Promise<GetAllUserAddressResM[]>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses`

        return this.get(uri)
    }

    getUserAddressByAddressUid(data: String): Promise<GetAllUserAddressResM>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data}`

        return this.get(uri)
    }

    getUserTimeSheetesByAddressUid(data: GetAllUserAddressResM): Promise<GetUserTimeSheetesByAddressUidResM[]>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.useraddresstimesheetwithshorttime+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.uid}/timeSheets`

        return this.get(uri, { headers, })
    }

    getUserTimeSheetByUid(addressUid: String, timeSheetUid: String): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.useraddresstimesheetwithshorttime+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${addressUid}/timeSheets/${timeSheetUid}`

        return this.get(uri, { headers, })
    }

    removeUserTimeSheet(addressUid: String, timesheetUid: String): Promise<void>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${addressUid}/timeSheets/${timesheetUid}`

        return this.delete(uri)
    }

    addUserTimeSheetStandart(data: AddUserTimeSheetStandartReqM): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.visualizationstandardtimesheet+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.userAddressUid}/timeSheets`

        return this.post(uri, { body: data, headers })
    }

    updateUserTimeSheetStandart(data: AddUserTimeSheetStandartReqM): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.visualizationstandardtimesheet+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.userAddressUid}/timeSheets/${data.uid}`

        return this.put(uri, { body: data, headers })
    }

    addUserTimeSheetWeekly(data: AddUserTimeSheetWeeklyReqM): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.visualizationweektimesheet+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.userAddressUid}/timeSheets`

        return this.post(uri, { body: data, headers })
    }

    updateUserTimeSheetWeekly(data: AddUserTimeSheetWeeklyReqM): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.visualizationweektimesheet+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.userAddressUid}/timeSheets/${data.uid}`

        return this.put(uri, { body: data, headers })
    }

    addUserTimeSheetMonthly(data: AddUserTimeSheetMonthlyReqM): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.visualizationmonthtimesheet+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.userAddressUid}/timeSheets`

        return this.post(uri, { body: data, headers })
    }

    updateUserTimeSheetMonthly(data: AddUserTimeSheetMonthlyReqM): Promise<any>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.visualizationmonthtimesheet+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${data.userAddressUid}/timeSheets/${data.uid}`

        return this.put(uri, { body: data, headers })
    }

    getWeekShedule(startDate: Date): Promise<GetWeekSheduleResM>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/schedule/week/${format(startDate, 'yyyy-MM-dd')}`

        return this.get(uri)
    }


    getDayShedule(startDate: Date): Promise<GetDaySheduleResM[]>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/schedule/day/${format(startDate, 'yyyy-MM-dd')}`

        return this.get(uri)
    }

    getAllOffPeriods(): Promise<GetAllOffPeriodsResM[]>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/offperiods`

        return this.get(uri)
    }

    addOffPeriod(data: AddOffPeriodReqM): Promise<any>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/offperiods`

        return this.post(uri, { body: data, })
    }

    removeOffPeriodByUid(uid: String): Promise<any>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/offperiods/${uid}`

        return this.delete(uri)
    }

    getNewAndAcceptedShedule(): Promise<GetNewAndAcceptedSheduleResM>
    {
        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/schedule/day`

        return this.get(uri)
    }

    getAvailableTimesByAddressUidAndDate(addressUid: String, date: Date): Promise<GetAvailableTimesByAddressUidAndDateResM[]>
    {
        let headers = {
            'Content-Type': 'application/vnd.agenda.useraddressavailabletimeswithshorttime+json',
        }

        let uri = this.coreApiUri + `/api/users/${this.globalData.getCurrentUser().uid}/addresses/${addressUid}/availableTimes/${format(date, 'yyyy-MM-dd')}`

        return this.get(uri, { headers })
    }

    changePassword(data: ChangePasswordReqM): Promise<any>
    {
        let uri = this.coreApiUri + '/api/users/changePassword'

        return this.post(uri, { body: data })
    }

    saveLanguageKey(data: SaveLanguageKeyReqM): Promise<any>
    {
        let uri = this.coreApiUri + '/api/users/saveLanguage'

        return this.post(uri, { body: data })
    }


    // ----- Helpers ----- //

    get(uri: string, init: MyRequestInit = {}): Promise<any>
    {
        init.headers = { ...this.defaultHeaders, ...init.headers }
        return super.get(uri, init)
    }

    post(uri: string, init: MyRequestInit = {}): Promise<any>
    {
        init.headers = { ...this.defaultHeaders, ...init.headers }
        return super.post(uri, init)
    }

    put(uri: string, init: MyRequestInit = {}): Promise<any>
    {
        init.headers = { ...this.defaultHeaders, ...init.headers }
        return super.put(uri, init)
    }

    delete(uri: string, init: MyRequestInit = {}): Promise<any>
    {
        init.headers = { ...this.defaultHeaders, ...init.headers }
        return super.delete(uri, init)
    }

}
