import { signupVerify } from "@/constants/routes/signup"
import { env } from "@/env/server"
import * as api from "@/lib/api"
import { serverErrorByStatus } from "@/server/errors/trpc"
import {
  initiateSaveCardSchema,
  subscriberIdSchema,
} from "@/server/routers/user/output"
import { createCounter } from "@/server/telemetry"
import { protectedProcedure, router, serviceProcedure } from "@/server/trpc"

import {
  addCreditCardInput,
  deleteCreditCardInput,
  saveCreditCardInput,
  signupInput,
} from "./input"

export const userMutationRouter = router({
  creditCard: router({
    add: protectedProcedure.input(addCreditCardInput).mutation(async function ({
      ctx,
      input,
    }) {
      console.info(
        "api.user.creditCard.add start",
        JSON.stringify({ query: { language: input.language } })
      )
      const apiResponse = await api.post(
        api.endpoints.v1.Profile.CreditCards.initiateSaveCard,
        {
          headers: {
            Authorization: `Bearer ${ctx.session.token.access_token}`,
          },
          body: {
            language: input.language,
            mobileToken: false,
            redirectUrl: `api/web/add-card-callback/${input.language}`,
          },
        }
      )

      if (!apiResponse.ok) {
        const text = await apiResponse.text()
        console.error(
          "api.user.creditCard.add error",
          JSON.stringify({
            query: { language: input.language },
            error: {
              status: apiResponse.status,
              statusText: apiResponse.statusText,
              error: text,
            },
          })
        )
        return null
      }

      const apiJson = await apiResponse.json()
      const verifiedData = initiateSaveCardSchema.safeParse(apiJson)
      if (!verifiedData.success) {
        console.error(
          "api.user.creditCard.add validation error",
          JSON.stringify({
            query: { language: input.language },
            error: verifiedData.error,
          })
        )
        return null
      }
      console.info(
        "api.user.creditCard.add success",
        JSON.stringify({ query: { language: input.language } })
      )
      return verifiedData.data.data
    }),
    save: protectedProcedure
      .input(saveCreditCardInput)
      .mutation(async function ({ ctx, input }) {
        console.info("api.user.creditCard.save start", JSON.stringify({}))
        const apiResponse = await api.post(
          api.endpoints.v1.Profile.CreditCards.transaction(input.transactionId),
          {
            headers: {
              Authorization: `Bearer ${ctx.session.token.access_token}`,
            },
          }
        )

        if (!apiResponse.ok) {
          const text = await apiResponse.text()
          console.error(
            "api.user.creditCard.save error",
            JSON.stringify({
              error: {
                status: apiResponse.status,
                statusText: apiResponse.statusText,
                text,
              },
            })
          )
          return false
        }
        console.info("api.user.creditCard.save success", JSON.stringify({}))
        return true
      }),
    delete: protectedProcedure
      .input(deleteCreditCardInput)
      .mutation(async function ({ ctx, input }) {
        console.info(
          "api.user.creditCard.delete start",
          JSON.stringify({ query: {} })
        )
        const apiResponse = await api.remove(
          api.endpoints.v1.Profile.CreditCards.deleteCreditCard(
            input.creditCardId
          ),
          {
            headers: {
              Authorization: `Bearer ${ctx.session.token.access_token}`,
            },
          }
        )

        if (!apiResponse.ok) {
          const text = await apiResponse.text()
          console.error(
            "api.user.creditCard.delete error",
            JSON.stringify({
              error: {
                status: apiResponse.status,
                statusText: apiResponse.statusText,
                text,
              },
              query: {},
            })
          )
          return false
        }
        console.info("api.user.creditCard.delete success", JSON.stringify({}))
        return true
      }),
  }),
  generatePreferencesLink: protectedProcedure.mutation(async function ({
    ctx,
  }) {
    const generatePreferencesLinkCounter = createCounter(
      "trpc.user",
      "generatePreferencesLink"
    )

    const metricsGeneratePreferencesLink = generatePreferencesLinkCounter.init()

    metricsGeneratePreferencesLink.start()

    const apiResponse = await api.get(api.endpoints.v1.Profile.subscriberId, {
      headers: {
        Authorization: `Bearer ${ctx.session.token.access_token}`,
      },
    })

    if (!apiResponse.ok) {
      await metricsGeneratePreferencesLink.httpError(apiResponse)
      return null
    }

    const data = await apiResponse.json()

    const validatedData = subscriberIdSchema.safeParse(data)

    if (!validatedData.success) {
      metricsGeneratePreferencesLink.validationError(validatedData.error)
      return null
    }

    const preferencesLink = new URL(env.SALESFORCE_PREFERENCE_BASE_URL)
    preferencesLink.searchParams.set("subKey", validatedData.data.subscriberId)

    metricsGeneratePreferencesLink.success()

    return preferencesLink.toString()
  }),
  signup: serviceProcedure.input(signupInput).mutation(async function ({
    ctx,
    input,
  }) {
    const signupCounter = createCounter("trpc.user", "signup")
    const metricsSignup = signupCounter.init()

    const apiResponse = await api.post(api.endpoints.v1.Profile.profile, {
      body: input,
      headers: {
        Authorization: `Bearer ${ctx.serviceToken}`,
      },
    })

    if (!apiResponse.ok) {
      await metricsSignup.httpError(apiResponse)
      const text = await apiResponse.text()
      throw serverErrorByStatus(apiResponse.status, text)
    }

    metricsSignup.success()

    return {
      success: true,
      redirectUrl: signupVerify[input.language],
    }
  }),
})
