/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import { useState, useEffect, useCallback, useMemo } from 'react'
import { useHistory } from 'react-router-dom'
import { ToastNotification } from '@/components/Toast'
import { DEVLAKE_ENDPOINT } from '@/utils/config'
import request from '@/utils/request'
import { NullConnection } from '@/data/NullConnection'
import {
  Providers,
  ProviderConnectionLimits,
  ConnectionStatus,
  ConnectionStatusLabels
} from '@/data/Providers'

import useNetworkOfflineMode from '@/hooks/useNetworkOfflineMode'

function useConnectionManager (
  {
    activeProvider,
    connectionId,
  },
  updateMode = false
) {
  const history = useHistory()
  const { handleOfflineMode } = useNetworkOfflineMode()

  const [provider, setProvider] = useState(activeProvider)
  const [name, setName] = useState()
  const [endpointUrl, setEndpointUrl] = useState()
  const [proxy, setProxy] = useState()
  const [token, setToken] = useState()
  const [initialTokenStore, setInitialTokenStore] = useState({
    0: '',
    1: '',
    2: ''
  })
  const [username, setUsername] = useState()
  const [password, setPassword] = useState()

  const [isSaving, setIsSaving] = useState(false)
  const [isFetching, setIsFetching] = useState(false)
  const [isRunning, setIsRunning] = useState(false)
  const [isTesting, setIsTesting] = useState(false)
  // eslint-disable-next-line no-unused-vars
  const [isDeleting, setIsDeleting] = useState(false)
  const [errors, setErrors] = useState([])
  const [showError, setShowError] = useState(false)
  const [testStatus, setTestStatus] = useState(0) //  0=Pending, 1=Success, 2=Failed
  const [testResponse, setTestResponse] = useState()
  const [allTestResponses, setAllTestResponses] = useState({})
  const [sourceLimits, setConnectionLimits] = useState(ProviderConnectionLimits)

  const [activeConnection, setActiveConnection] = useState(NullConnection)
  const [allConnections, setAllConnections] = useState([])
  const [allProviderConnections, setAllProviderConnections] = useState([])
  const [domainRepositories, setDomainRepositories] = useState([])
  const [testedConnections, setTestedConnections] = useState([])
  const [connectionCount, setConnectionCount] = useState(0)
  const [connectionLimitReached, setConnectionLimitReached] = useState(false)

  const [saveComplete, setSaveComplete] = useState(false)
  const [deleteComplete, setDeleteComplete] = useState(false)
  const connectionTestPayload = useMemo(() => ({ endpoint: endpointUrl, username, password, token, proxy }), [endpointUrl, password, proxy, token, username])

  const testConnection = useCallback(
    (
      notify = true,
      manualPayload = {},
      onSuccess = () => {},
      onFail = () => {}
    ) => {
      setIsTesting(true)
      setShowError(false)
      ToastNotification.clear()
      setTestResponse(null)

      const runTest = async () => {
        const payload = Object.keys(manualPayload).length > 0 ? manualPayload : connectionTestPayload
        const testUrl = `${DEVLAKE_ENDPOINT}/plugins/${provider.id}/test`
        console.log(
          'INFO >>> Endpoint URL & Payload for testing: ',
          testUrl,
          payload
        )
        const res = await request.post(testUrl, payload)
        setTestResponse(res.data)
        if ([Providers.GITHUB].includes(provider.id)) {
          console.log('>>> SETTING TOKEN TEST RESPONSE FOR TOKEN >>>', manualPayload?.token || connectionTestPayload.token)
          setAllTestResponses(tRs => ({ ...tRs, [manualPayload?.token]: res.data }))
        }
        if (res.data?.success && res.status === 200) {
          setIsTesting(false)
          setTestStatus(1)
          if (notify) {
            ToastNotification.show({
              message: `Connection test OK. ${payload.endpoint}`,
              intent: 'success',
              icon: 'small-tick',
            })
          }
          onSuccess(res)
        } else {
          setIsTesting(false)
          setTestStatus(2)
          const errorMessage =
            'Connection test FAILED. ' + (res.data ? res.data.message : '')
          if (notify) {
            ToastNotification.show({
              message: errorMessage,
              intent: 'danger',
              icon: 'error',
            })
          }
          onFail(res)
        }
      }
      runTest()
    },
    [provider?.id, connectionTestPayload]
  )

  const saveConnection = (configurationSettings = {}) => {
    setIsSaving(true)
    let connectionPayload = { ...configurationSettings }
    switch (provider.id) {
      case Providers.JIRA:
        connectionPayload = {
          name: name,
          endpoint: endpointUrl,
          username: username,
          password: password,
          proxy: proxy,
          ...connectionPayload,
        }
        break
      case Providers.GITHUB:
        connectionPayload = {
          name: name,
          endpoint: endpointUrl,
          token: token,
          proxy: proxy,
          ...connectionPayload,
        }
        break
      case Providers.JENKINS:
      // eslint-disable-next-line max-len
        connectionPayload = {
          name: name,
          endpoint: endpointUrl,
          username: username,
          password: password,
          ...connectionPayload,
        }
        break
      case Providers.GITLAB:
        connectionPayload = {
          name: name,
          endpoint: endpointUrl,
          token: token,
          proxy: proxy,
          ...connectionPayload,
        }
        break
    }

    let saveResponse = {
      success: false,
      connection: {
        ...connectionPayload,
      },
      errors: [],
    }

    const saveConfiguration = async (configPayload) => {
      try {
        setShowError(false)
        setErrors([])
        ToastNotification.clear()
        const s = await request.post(
          `${DEVLAKE_ENDPOINT}/plugins/${provider.id}/connections`,
          configPayload
        )
        console.log('>> CONFIGURATION SAVED SUCCESSFULLY', configPayload, s)
        saveResponse = {
          ...saveResponse,
          success: [200, 201].includes(s.status),
          connection: { ...s.data },
          errors: s.isAxiosError ? [s.message] : [],
        }
      } catch (e) {
        saveResponse.errors.push(e.message)
        setErrors(saveResponse.errors)
        console.log('>> CONFIGURATION FAILED TO SAVE', configPayload, e)
      }
    }

    const modifyConfiguration = async (configPayload) => {
      try {
        setShowError(false)
        setErrors([])
        ToastNotification.clear()
        // eslint-disable-next-line max-len
        const s = await request.patch(
          `${DEVLAKE_ENDPOINT}/plugins/${provider.id}/connections/${
            activeConnection.id || activeConnection.ID
          }`,
          configPayload
        )
        const silentRefetch = true
        console.log('>> CONFIGURATION MODIFIED SUCCESSFULLY', configPayload, s)
        saveResponse = {
          ...saveResponse,
          success: [200, 201].includes(s.status),
          connection: { ...s.data },
          errors: s.isAxiosError ? [s.message] : [],
        }
        fetchConnection(silentRefetch)
      } catch (e) {
        saveResponse.errors.push(e.message)
        setErrors(saveResponse.errors)
        console.log('>> CONFIGURATION FAILED TO UPDATE', configPayload, e)
      }
    }

    if (updateMode && activeConnection?.id !== null) {
      modifyConfiguration(connectionPayload)
    } else {
      saveConfiguration(connectionPayload)
    }

    setTimeout(() => {
      if (saveResponse.success && errors.length === 0) {
        ToastNotification.show({
          message: 'Connection saved successfully.',
          intent: 'success',
          icon: 'small-tick',
        })
        setShowError(false)
        setIsSaving(false)
        setSaveComplete(saveResponse.connection)
        if (
          [Providers.GITHUB, Providers.JIRA, Providers.GITLAB].includes(provider.id) &&
          token !== '' &&
          token?.toString().split(',').length > 1
        ) {
          testConnection()
        }
        if (!updateMode) {
          history.push(`/integrations/${provider.id}`)
        }
      } else {
        ToastNotification.show({
          message: 'Connection failed to save, please try again.',
          intent: 'danger',
          icon: 'error',
        })
        setShowError(true)
        setIsSaving(false)
        setSaveComplete(false)
      }
    }, 2000)
  }

  const runCollection = (options = {}) => {
    setIsRunning(true)
    ToastNotification.show({
      message: 'Triggered Collection Process',
      intent: 'info',
      icon: 'info',
    })
    console.log('>> RUNNING COLLECTION PROCESS', isRunning)
    // Run Collection Tasks...
  }

  const fetchConnection = useCallback(
    (silent = false, notify = false, cId = null) => {
      console.log(`>> FETCHING CONNECTION [PROVIDER = ${provider.id}]....`)
      try {
        setIsFetching(!silent)
        setErrors([])
        ToastNotification.clear()
        console.log('>> FETCHING CONNECTION SOURCE')
        const fetch = async () => {
          const f = await request.get(
            `${DEVLAKE_ENDPOINT}/plugins/${provider.id}/connections/${cId || connectionId}`
          )
          const connectionData = f.data
          console.log('>> RAW CONNECTION DATA FROM API...', connectionData)
          setActiveConnection({
            ...connectionData,
            ID: connectionData.ID || connectionData.id,
            name: connectionData.name || connectionData.Name,
            endpoint: connectionData.endpoint || connectionData.Endpoint,
            proxy: connectionData.proxy || connectionData.Proxy,
            username: connectionData.username || connectionData.Username,
            password: connectionData.password || connectionData.Password,
            token: connectionData.token || connectionData.auth
          })
          setTimeout(() => {
            setIsFetching(false)
          }, 500)
        }
        fetch()
      } catch (e) {
        setIsFetching(false)
        setActiveConnection(NullConnection)
        setErrors([e.message])
        ToastNotification.show({
          message: `${e}`,
          intent: 'danger',
          icon: 'error',
        })
        console.log('>> FAILED TO FETCH CONNECTION', e)
      }
    },
    [provider?.id, connectionId]
  )

  const fetchAllConnections = useCallback(
    async (notify = false, allSources = false) => {
      try {
        setIsFetching(true)
        setErrors([])
        ToastNotification.clear()
        console.log('>> FETCHING ALL CONNECTION SOURCES')
        let c = null
        if (allSources) {
          const aC = await Promise.all([
            request.get(
              `${DEVLAKE_ENDPOINT}/plugins/${Providers.JIRA}/connections`
            ),
            request.get(
              `${DEVLAKE_ENDPOINT}/plugins/${Providers.GITLAB}/connections`
            ),
            request.get(
              `${DEVLAKE_ENDPOINT}/plugins/${Providers.JENKINS}/connections`
            ),
            request.get(
              `${DEVLAKE_ENDPOINT}/plugins/${Providers.GITHUB}/connections`
            ),
          ])
          const builtConnections = aC
            .map((providerResponse) => [].concat(providerResponse.data || []).map(c => ({
              ...c,
              connectionId: c.id,
              provider: providerResponse.config?.url?.split('/')[3],
              // @todo: inject realtime connection status...
              status: ConnectionStatus.ONLINE
            })))
          setAllProviderConnections(builtConnections.flat())
          console.log(
            '>> ALL SOURCE CONNECTIONS: FETCHING ALL CONNECTION FROM ALL DATA SOURCES'
          )
          console.log('>> ALL SOURCE CONNECTIONS: ', aC)
        } else {
          c = await request.get(
            `${DEVLAKE_ENDPOINT}/plugins/${provider.id}/connections`
          )
        }

        console.log('>> RAW ALL CONNECTIONS DATA FROM API...', c?.data)
        const providerConnections = []
          .concat(Array.isArray(c?.data) ? c?.data : [])
          .map((conn, idx) => {
            return {
              ...conn,
              status: ConnectionStatus.OFFLINE,
              ID: conn.ID || conn.id,
              name: conn.name,
              endpoint: conn.endpoint,
              errors: [],
            }
          })
        if (notify) {
          ToastNotification.show({
            message: 'Loaded all connections.',
            intent: 'success',
            icon: 'small-tick',
          })
        }
        setAllConnections(providerConnections)
        setConnectionCount(c?.data?.length)
        setConnectionLimitReached(
          sourceLimits[provider.id] &&
            c.data?.length >= sourceLimits[provider.id]
        )
        setIsFetching(false)
      } catch (e) {
        console.log('>> FAILED TO FETCH ALL CONNECTIONS', e)
        ToastNotification.show({
          message: `Failed to Load Connections - ${e.message}`,
          intent: 'danger',
          icon: 'error',
        })
        setIsFetching(false)
        setAllConnections([])
        setConnectionCount(0)
        setConnectionLimitReached(false)
        setErrors([e.message])
        handleOfflineMode(e.response?.status, e.response)
      }
    },
    [provider?.id, sourceLimits, handleOfflineMode]
  )

  const deleteConnection = useCallback(
    async (connection) => {
      try {
        setIsDeleting(true)
        setErrors([])
        console.log('>> TRYING TO DELETE CONNECTION...', connection)
        const d = await request.delete(
          `${DEVLAKE_ENDPOINT}/plugins/${provider.id}/connections/${
            connection.ID || connection.id
          }`
        )
        console.log('>> CONNECTION DELETED...', d)
        setIsDeleting(false)
        setDeleteComplete({
          provider: activeProvider,
          connection: d.data,
        })
      } catch (e) {
        setIsDeleting(false)
        setDeleteComplete(false)
        setErrors([e.message])
        console.log('>> FAILED TO DELETE CONNECTION', e)
      }
    },
    [provider?.id, activeProvider]
  )

  const getConnectionName = useCallback((connectionId, connections) => {
    const source = connections.find((s) => s.id === connectionId)
    return source ? source.title : '(Instance)'
  }, [])

  const testAllConnections = useCallback(
    (connections) => {
      console.log('>> TESTING ALL CONNECTION SOURCES...')
      connections.forEach((c, cIdx) => {
        console.log('>>> TESTING CONNECTION INSTANCE...', c)
        const notify = false
        const payload = {
          endpoint: c.endpoint,
          username: c.username,
          password: c.password,
          token: c.token,
          proxy: c.proxy,
        }
        const onSuccess = (res) => {
          setTestedConnections((testedConnections) => [
            ...new Set([
              ...testedConnections.filter((oC) => oC.id !== c.id),
              { ...c, status: ConnectionStatus.ONLINE },
            ]),
          ])
        }
        const onFail = (res) => {
          setTestedConnections((testedConnections) => [
            ...new Set([
              ...testedConnections.filter((oC) => oC.ID !== c.ID),
              { ...c, status: ConnectionStatus.DISCONNECTED },
            ]),
          ])
        }
        testConnection(notify, payload, onSuccess, onFail)
      })
    },
    [testConnection]
  )

  const fetchDomainLayerRepositories = useCallback(() => {
    console.log('>> FETCHING DOMAIN LAYER REPOS....')
    try {
      setIsFetching(true)
      setErrors([])
      ToastNotification.clear()
      const fetch = async () => {
        const r = await request.get(`${DEVLAKE_ENDPOINT}/domainlayer/repos`)
        console.log('>> RAW REPOSITORY DATA FROM API...', r.data?.repos)
        setDomainRepositories(r.data?.repos || [])
        setTimeout(() => {
          setIsFetching(false)
        }, 500)
      }
      fetch()
    } catch (e) {
      setIsFetching(false)
      setDomainRepositories([])
      setErrors([e.message])
      ToastNotification.show({
        message: `${e}`,
        intent: 'danger',
        icon: 'error',
      })
      console.log('>> FAILED TO FETCH DOMAIN LAYER REPOS', e)
    }
  }, [])

  const clearConnection = useCallback(() => {
    setName('')
    setEndpointUrl('')
    setUsername('')
    setPassword('')
    setToken('')
    setInitialTokenStore({
      0: '',
      1: '',
      2: ''
    })
    setProxy('')
  }, [])

  useEffect(() => {
    if (activeConnection && activeConnection.id !== null) {
      const connectionToken = activeConnection.auth || activeConnection.token || activeConnection.basicAuthEncoded
      setName(activeConnection.name)
      setEndpointUrl(activeConnection.endpoint)
      switch (provider.id) {
        case Providers.JENKINS:
          setUsername(activeConnection.username)
          setPassword(activeConnection.password)
          break
        case Providers.GITLAB:
          setToken(activeConnection.basicAuthEncoded || activeConnection.token || activeConnection.auth)
          setProxy(activeConnection.Proxy || activeConnection.proxy)
          break
        case Providers.GITHUB:
          setToken(connectionToken)
          setInitialTokenStore(connectionToken?.split(',')?.reduce((tS, cT, id) => ({ ...tS, [id]: cT }), {}))
          setProxy(activeConnection.Proxy || activeConnection.proxy)
          break
        case Providers.JIRA:
        // setToken(activeConnection.basicAuthEncoded || activeConnection.token)
          setUsername(activeConnection.username)
          setPassword(activeConnection.password)
          setProxy(activeConnection.Proxy || activeConnection.proxy)
          break
      }
      ToastNotification.clear()
      // ToastNotification.show({ message: `Fetched settings for ${activeConnection.name}.`, intent: 'success', icon: 'small-tick' })
      console.log('>> FETCHED CONNECTION FOR MODIFY', activeConnection)
    }
  }, [activeConnection, provider?.id])

  useEffect(() => {
    if (saveComplete && saveComplete.ID) {
      console.log('>>> CONNECTION MANAGER - SAVE COMPLETE EFFECT RUNNING...')
      setActiveConnection((ac) => {
        return {
          ...ac,
          ...saveComplete,
        }
      })
    }
  }, [saveComplete])

  useEffect(() => {
    console.log(
      '>> CONNECTION MANAGER - SELECTING ACTIVE PROVIDER...',
      provider
    )
    if (provider && provider?.id) {
      // console.log(activeProvider)
    }
  }, [provider])

  useEffect(() => {
    if (connectionId !== null && connectionId !== undefined) {
      console.log('>>>> CONFIGURING CONNECTION ID ... ', connectionId)
      fetchConnection()
    }
  }, [connectionId, fetchConnection])

  useEffect(() => {
    console.log('>> TESTED CONNECTION RESULTS...', testedConnections)
  }, [testedConnections])

  useEffect(() => {
    console.log('>> CONNECTION MANAGER, ACTIVE PROVIDER CHANGED ====>', activeProvider)
    setProvider(activeProvider)
  }, [activeProvider])

  return {
    activeConnection,
    fetchConnection,
    fetchAllConnections,
    fetchDomainLayerRepositories,
    testAllConnections,
    testConnection,
    saveConnection,
    deleteConnection,
    runCollection,
    isSaving,
    isTesting,
    isFetching,
    errors,
    showError,
    testStatus,
    name,
    endpointUrl,
    proxy,
    username,
    password,
    token,
    initialTokenStore,
    provider,
    setActiveConnection,
    setProvider,
    setName,
    setEndpointUrl,
    setProxy,
    setToken,
    setInitialTokenStore,
    setUsername,
    setPassword,
    setIsSaving,
    setIsTesting,
    setIsFetching,
    setErrors,
    setShowError,
    setTestStatus,
    setTestResponse,
    setAllTestResponses,
    setConnectionLimits,
    setSaveComplete,
    allConnections,
    allProviderConnections,
    domainRepositories,
    testedConnections,
    sourceLimits,
    connectionCount,
    connectionLimitReached,
    connectionTestPayload,
    Providers,
    saveComplete,
    deleteComplete,
    getConnectionName,
    clearConnection,
    testResponse,
    allTestResponses
  }
}

export default useConnectionManager
