import { NextAuthOptions } from 'next-auth'
import CredentialsProvider from 'next-auth/providers/credentials'
import { JWT } from 'next-auth/jwt'

declare module 'next-auth' {
  interface Session {
    user: {
      name?: string | null
      surname?: string | null
      email?: string | null
      phone_number?: string | null
      image?: string | null
    }
    accessToken?: string
    refreshToken?: string
    expiresAt?: number
  }

  interface User {
    id: string
    email: string
    name?: string
    accessToken?: string
    refreshToken?: string
  }

  interface JWT {
    accessToken?: string
    refreshToken?: string
    expiresAt?: number
    error?: string
  }
}

interface GoogleToken extends JWT {
  accessToken?: string
  refreshToken?: string
  expiresAt?: number | undefined
  error?: string
}

async function refreshAccessToken(token: GoogleToken): Promise<GoogleToken> {
  try {
    const response = await fetch(`${process.env.BACKEND_URL}/auth/refresh/`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        refresh: token.refreshToken,
      }),
    })

    if (!response.ok) {
      const errorData = await response.json()
      throw errorData
    }

    const refreshedTokens = await response.json()

    return {
      ...token,
      accessToken: refreshedTokens.access,
      refreshToken: refreshedTokens.refresh ?? token.refreshToken,
      expiresAt: refreshedTokens.expires_at,
    }
  } catch (error) {
    console.error('Refresh error:', error)
    return {
      ...token,
      error: 'RefreshAccessTokenError',
    }
  }
}

export const authOptions: NextAuthOptions = {
  providers: [
    //логин
    CredentialsProvider({
      id: 'credentials',
      name: 'Credentials',
      credentials: {
        login: { label: 'Login', type: 'text' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        try {
          const res = await fetch(`${process.env.BACKEND_URL}/auth/login/`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              login: credentials?.login,
              password: credentials?.password,
            }),
          })

          const data = await res.json()

          if (!res.ok) {
            throw new Error(data.error || 'Authentication failed')
          }

          return {
            id: data.user.id.toString(),
            email: data.user.email,
            name: data.user.firstName,
            accessToken: data.access,
            refreshToken: data.refresh,
          }
        } catch (error) {
          console.error('Login error:', error)
          return null
        }
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user, account }) {
      if (user && account) {
        if (account.type === 'credentials') {
          return {
            ...token,
            accessToken: user.accessToken,
            refreshToken: user.refreshToken,
            expiresAt: Math.floor(Date.now() / 1000) + 15 * 60, // 15 минут
          }
        } else {
          return {
            ...token,
            accessToken: account.access_token,
            refreshToken: account.refresh_token,
            expiresAt: account.expires_at,
          }
        }
      }

      // проверяем не истекает ли токен в ближайшие 5 минут
      const expiresAt = token.expiresAt as number | undefined
      if (
        typeof expiresAt === 'number' &&
        Date.now() < (expiresAt - 5 * 60) * 1000 // обновляем за 5 минут до истечения
      ) {
        return token
      }

      return refreshAccessToken(token as GoogleToken)
    },
    async session({ session, token }) {
      if (token) {
        session.accessToken = token.accessToken as string
        session.refreshToken = token.refreshToken as string
      }
      return session
    },
  },
}
