// summary : X API tweets list
// keywords : scala, zio, sttp, x-api
// publish : gist
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : 47b77580-a424-456d-a453-c57caf17ecd1
// created-on : 2025-04-07T23:28:49+02:00
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file

//> using scala 3.6.4
//> using dep dev.zio::zio:2.1.17
//> using dep com.softwaremill.sttp.client4::zio:4.0.0
//> using dep com.softwaremill.sttp.client4::zio-json:4.0.0
////> using objectWrapper

// https://developer.x.com/en
// TOK="Authorization: Bearer $SOCIAL_API_X_TOKEN"
// ID=$(curl -s -H $TOK "https://api.x.com/2/users/by/username/$SOCIAL_API_X_USERNAME" | jq -r .data.id)
// curl -s -H $TOK "https://api.x.com/2/users/$ID/tweets?max_results=10"

import zio.*
import sttp.client4.*
import sttp.client4.httpclient.zio.HttpClientZioBackend
import sttp.client4.ziojson.*
import zio.json.JsonCodec

case class Tweet(id: String, text: String) derives JsonCodec
case class TweetsResponse(data: List[Tweet]) derives JsonCodec

case class User(id: String, name: String, username: String) derives JsonCodec
case class UserResponse(data: User) derives JsonCodec

val app = for {
  token          <- System.env("SOCIAL_API_X_TOKEN").someOrFail("NO CREDENTIAL TOKEN PROVIDED")
  username       <- System.env("SOCIAL_API_X_USERNAME").someOrFail("NO CREDENTIAL USERNAME PROVIDED")
  _              <- Console.printLine(s"Querying X API for user $username")
  backend        <- HttpClientZioBackend.apply()
  queryUser       = basicRequest
                      .get(uri"https://api.x.com/2/users/by/username/$username")
                      .header("Authorization", s"Bearer $token")
                      .response(asJson[UserResponse])
  responseUser   <- backend.send(queryUser).map(_.body)
  id             <- ZIO.from(responseUser).map(_.data.id)
  _              <- Console.printLine(s"Got user id $id")
  queryTweets     = basicRequest
                      .get(uri"https://api.x.com/2/users/$id/tweets?max_results=10")
                      .header("Authorization", s"Bearer $token")
                      .response(asJson[TweetsResponse])
  _              <- Console.printLine("Querying X API")
  responseTweets <- backend.send(queryTweets).map(_.body)
  posts          <- ZIO.fromEither(responseTweets).map(_.data)
  _              <- Console.printLine(s"Got ${posts.size} posts")
} yield ()

Unsafe.unsafe(implicit u => Runtime.default.unsafe.run(app))