"use client"

import { createContext, useContext, useEffect, useState, useCallback } from "react"
import {
  configuredBackendUrl,
  defaultDataSourceMode,
  isBackendUrlLocked,
  LOCAL_DEFAULT_BACKEND_URL,
  resolveStoredBackendUrl,
} from "@/lib/backend-url"

// ── types ─────────────────────────────────────────────────────────────────────

export type DataSourceMode = "mock" | "live"

interface DataSourceContextValue {
  mode:          DataSourceMode
  setMode:       (m: DataSourceMode) => void
  backendUrl:    string
  setBackendUrl: (url: string) => void
  backendUrlLocked: boolean
  /** undefined = не проверялось, true = OK, false = недоступен */
  backendStatus: boolean | undefined
  checkBackend:  () => Promise<void>
}

// ── context ───────────────────────────────────────────────────────────────────

const DataSourceContext = createContext<DataSourceContextValue | null>(null)

const LS_MODE    = "routerlists:data-source"
const LS_BACKEND = "routerlists:backend-url"

function readStoredMode(): DataSourceMode {
  if (typeof window === "undefined") return defaultDataSourceMode()
  const stored = localStorage.getItem(LS_MODE) as DataSourceMode | null
  return stored === "mock" || stored === "live" ? stored : defaultDataSourceMode()
}

function readStoredBackendUrl(): string {
  if (typeof window === "undefined") return LOCAL_DEFAULT_BACKEND_URL
  return resolveStoredBackendUrl(localStorage.getItem(LS_BACKEND))
}

function normalizeBackendUrl(url: string): string {
  return url.trim().replace(/\/$/, "")
}

export function DataSourceProvider({ children }: { children: React.ReactNode }) {
  const [mode, setModeState] = useState<DataSourceMode>(() =>
    typeof window === "undefined" ? defaultDataSourceMode() : readStoredMode(),
  )
  const [backendUrl, setBackendUrlState] = useState(() =>
    typeof window === "undefined" ? LOCAL_DEFAULT_BACKEND_URL : readStoredBackendUrl(),
  )
  const [backendStatus, setBackendStatus] = useState<boolean | undefined>(undefined)
  const backendUrlLocked = isBackendUrlLocked()

  useEffect(() => {
    if (configuredBackendUrl().kind !== "same-origin") return
    setBackendUrlState(window.location.origin)
  }, [])

  const setMode = useCallback((m: DataSourceMode) => {
    setModeState(m)
    localStorage.setItem(LS_MODE, m)
  }, [])

  const setBackendUrl = useCallback((url: string) => {
    if (backendUrlLocked) return
    const normalized = normalizeBackendUrl(url)
    setBackendUrlState(normalized)
    localStorage.setItem(LS_BACKEND, normalized)
  }, [backendUrlLocked])

  const checkBackend = useCallback(async () => {
    const url = normalizeBackendUrl(backendUrl)
    try {
      const res = await fetch(`${url}/health`, { signal: AbortSignal.timeout(3000) })
      setBackendStatus(res.ok)
    } catch {
      setBackendStatus(false)
    }
  }, [backendUrl])

  useEffect(() => {
    if (mode === "live") queueMicrotask(() => { void checkBackend() })
  }, [mode, checkBackend])

  return (
    <DataSourceContext.Provider
      value={{ mode, setMode, backendUrl, setBackendUrl, backendUrlLocked, backendStatus, checkBackend }}
    >
      {children}
    </DataSourceContext.Provider>
  )
}

export function useDataSource(): DataSourceContextValue {
  const ctx = useContext(DataSourceContext)
  if (!ctx) throw new Error("useDataSource must be used inside <DataSourceProvider>")
  return ctx
}
