function detectBrowser() {
  const userAgent = navigator.userAgent
  if (userAgent.indexOf('Edg') > -1) {
    return 'Microsoft Edge'
  } else if (userAgent.indexOf('Chrome') > -1) {
    return 'Chrome'
  } else if (userAgent.indexOf('Firefox') > -1) {
    return 'Firefox'
  } else if (userAgent.indexOf('Safari') > -1) {
    return 'Safari'
  } else if (userAgent.indexOf('Opera') > -1) {
    return 'Opera'
  } else if (userAgent.indexOf('Trident') > -1 || userAgent.indexOf('MSIE') > -1) {
    return 'Internet Explorer'
  }

  return 'Unknown'
}

type Endpoint = {
  resource: string
  method: string
}

type View = {
  Id: string
  Name: string
  CollectionType: string
  ParentId: string
}

type ViewList = {
  Items: View[]
}

type NextUp = {
  Items: Item[]
}

type Item = {
  Name: string
  OriginalTitle: string
  Id: string
  Type: string
  OfficialRating: string
  ImageTags: ImageTags
  CommunityRating: number
  ProductionYear: number
  IndexNumber?: number
  ParentIndexNumber?: number
  SeriesName?: string
  SeriesId?: string
  Overview: string
  RunTimeTicks: number
  ParentThumbItemId?: string
  ParentThumbImageTag?: string
  ParentBackdropItemId?: string
  ParentBackdropImageTags?: string[]
  SeriesPrimaryImageTag?: string
  UserData?: UserData
}

type UserData = {
  UnplayedItemCount: number
}

type ImageTags = {
  Primary?: string
  Thumb?: string
}

type User = {
  Name: string
  Host: string
  Id: string
  Views?: View[]
}

export type { User, View, Item, ViewList }

class JFApi {
  request<T>(endpoint: Endpoint): Promise<T | null> {
    const host = localStorage.getItem('jf_host') === null ? '' : localStorage.getItem('jf_host')
    return new Promise((resolve) => {
      fetch(`${host}${endpoint.resource}`, {
        method: endpoint?.method,
        headers: {
          Authorization: `MediaBrowser Client="Featherfin", Device="${detectBrowser()}", DeviceId="abc123", Version="v0.0.1", Token="${localStorage.getItem('jfauth_token')}"`,
        },
      })
        .then(async (response) => {
          const data = await response.json()
          resolve(data as T)
        })
        .catch((error) => {
          console.log(error)
          resolve(null)
        })
    })
  }
  LoadViews(userid: string): Promise<ViewList | null> {
    return this.request({
      resource: `/UserViews?userId=${userid}`,
      method: 'GET',
    })
  }
  GetLatest(userid: string, view: View): Promise<Item[] | null> {
    return this.request({
      resource: `/Users/${userid}/Items/Latest?Limit=16&Fields=PrimaryImageAspectRatio%2CPath&ImageTypeLimit=1&EnableImageTypes=Primary%2CBackdrop%2CThumb&ParentId=${view.Id}`,
      method: 'GET',
    })
  }
  GetNextUp(): Promise<NextUp | null> {
    return this.request({
      resource: `/Shows/NextUp?Limit=24&Fields=PrimaryImageAspectRatio%2CDateCreated%2CPath%2CMediaSourceCount&UserId=f7967316db8e46b4960690d0df2c0163&ImageTypeLimit=1&EnableImageTypes=Primary%2CBackdrop%2CBanner%2CThumb&EnableTotalRecordCount=false&DisableFirstEpisode=false&NextUpDateCutoff=2023-12-03T21%3A55%3A33.690Z&EnableResumable=false&EnableRewatching=false`,
      method: 'GET',
    })
  }
  GetItem(userid: string, itemId: string): Promise<Item | null> {
    return this.request({
      resource: `/Items/${itemId}?userId=${userid}`,
      method: 'GET',
    })
  }
  ThumbImageUrl(itemId: string, imgTag: string) {
    const host = localStorage.getItem('jf_host') === null ? '' : localStorage.getItem('jf_host')
    return `${host}/Items/${itemId}/Images/Thumb?fillHeight=267&fillWidth=474&quality=96&tag=${imgTag}`
  }
  BackdropImageUrl(itemId: string, imgTag: string) {
    const host = localStorage.getItem('jf_host') === null ? '' : localStorage.getItem('jf_host')
    return `${host}/Items/${itemId}/Images/Backdrop?fillHeight=267&fillWidth=474&quality=96&tag=${imgTag}`
  }
  PrimaryImageUrl(itemId: string, imgTag: string) {
    const host = localStorage.getItem('jf_host') === null ? '' : localStorage.getItem('jf_host')
    return `${host}/Items/${itemId}/Images/Primary?fillHeight=446&fillWidth=297&quality=96&tag=${imgTag}`
  }
  Login(host: string, username: string, password: string): Promise<User | null> {
    return new Promise((resolve) => {
      fetch(`${host}/Users/authenticatebyname`, {
        method: 'POST',
        body: JSON.stringify({ Username: username, Pw: password }),
        headers: {
          'Content-Type': 'application/json',
          Authorization: `MediaBrowser Client="Featherfin", Device="${detectBrowser()}", DeviceId="abc123", Version="v0.0.1", Token="${localStorage.getItem('jfauth_token')}"`,
        },
      })
        .then((r) => r.json().then((data) => ({ status: r.status, body: data })))
        .then((data) => {
          console.log(data)
          if (data.status !== 200) {
            // bad
            resolve(null)
          } else {
            localStorage.setItem('jfauth_token', data.body.AccessToken)
            resolve({
              Name: data.body.User.Name,
              Id: data.body.User.Id,
              Host: 'http://192.168.0.63:30013',
            })
          }
        })
    })
  }
  Logout() {
    return this.request({
      resource: '/Sessions/Logout',
      method: 'POST',
    })
      .then((data) => {
        localStorage.removeItem('jfauth_token')
        return data
      })
      .catch((err) => {
        return err
      })
  }
}

export default new JFApi()

/*
- /UserViews?userId=XYZ - returns [Library]
- /Latest?...&ParentId=Library.Id - returns latest in library
- /Resume?...&MediaTypes=Video - returns unfinished playback
- /NextUp?... - returns [Episode]
- /Users/authenticatebyname body:{Username: "xyz", Pw: "xyz123"} returns: AccessToken, User, SessionInfo
Authentication is done by appending 'Token="MyTokenXYZ123"' to Authorization header
- /Users/User.Id - returns: User
- /Users/User.Id/Items?SortBy=DateCreated%2CSortName%2CProductionYear&SortOrder=Descending&IncludeItemTypes=Movie&Recursive=true&Fields=PrimaryImageAspectRatio%2CMediaSourceCount&ImageTypeLimit=1&EnableImageTypes=Primary%2CBackdrop%2CBanner%2CThumb&StartIndex=0&ParentId=f137a2dd21bbc1b99aa5c0f6bf02a805&Limit=100 - returns [Item<Movie>]
- /Users/User.Id/Items/Item.Id - FullItem
- /Items/Item.Id/Similar?userId=User.Id&limit=12&fields=PrimaryImageAspectRatio - returns similar items
- /Items/Item.Id/Images/Primary?fillHeight=713&fillWidth=500&quality=96&tag=Item.ImageTags.Primary - returns Primary Image
- /.../Images/Thumb?...&tag=Episode.ParentThumbImageTag
- /Sessions/Logout - logout
*/
