"use client"

import { createContext, useContext, useState, useCallback, type ReactNode } from "react"
import useSWR, { mutate } from "swr"

// Types for database entities
export interface User {
  id: string
  name: string
  email: string
  avatar_url: string | null
  role: string
  subscription_type: string
  is_active: boolean
  is_verified: boolean
  created_at: string
  last_login_at: string | null
}

export interface Track {
  id: string
  title: string
  artist_id: string
  artist_name?: string
  album_id: string | null
  album_title?: string
  duration_ms: number
  total_streams: number
  status: string
  cover_url: string | null
}

export interface Artist {
  id: string
  name: string
  avatar_url: string | null
  total_followers: number
  total_streams: number
  monthly_listeners: number
  is_verified: boolean
  bio: string | null
  country: string | null
}

export interface Album {
  id: string
  title: string
  artist_id: string
  artist_name?: string
  cover_url: string | null
  total_tracks: number
  release_date: string | null
  total_streams: number
  album_type: string
  status: string
}

export interface Genre {
  id: string
  name: string
  slug: string
  color: string | null
  is_featured: boolean
  track_count: number
}

const fetcher = (url: string) => fetch(url).then((res) => res.json())

interface AdminContextType {
  // Data
  users: User[]
  tracks: Track[]
  artists: Artist[]
  albums: Album[]
  genres: Genre[]
  isLoading: boolean

  // User operations
  addUser: (user: Partial<User>) => Promise<void>
  updateUser: (id: string, data: Partial<User>) => Promise<void>
  deleteUser: (id: string) => Promise<void>
  deleteUsers: (ids: string[]) => Promise<void>
  suspendUser: (id: string) => Promise<void>

  // Track operations
  addTrack: (track: Partial<Track>) => Promise<void>
  updateTrack: (id: string, data: Partial<Track>) => Promise<void>
  deleteTrack: (id: string) => Promise<void>
  deleteTracks: (ids: string[]) => Promise<void>

  // Artist operations
  addArtist: (artist: Partial<Artist>) => Promise<void>
  updateArtist: (id: string, data: Partial<Artist>) => Promise<void>
  deleteArtist: (id: string) => Promise<void>
  toggleArtistVerification: (id: string) => Promise<void>

  // Album operations
  addAlbum: (album: Partial<Album>) => Promise<void>
  updateAlbum: (id: string, data: Partial<Album>) => Promise<void>
  deleteAlbum: (id: string) => Promise<void>

  // Genre operations
  addGenre: (genre: Partial<Genre>) => Promise<void>
  updateGenre: (id: string, data: Partial<Genre>) => Promise<void>
  deleteGenre: (id: string) => Promise<void>

  // Toast
  showToast: (message: string, type?: "success" | "error" | "info") => void
  toast: { message: string; type: "success" | "error" | "info" } | null

  // Refresh
  refreshData: () => void
}

const AdminContext = createContext<AdminContextType | undefined>(undefined)

export function AdminProvider({ children }: { children: ReactNode }) {
  const [toast, setToast] = useState<{ message: string; type: "success" | "error" | "info" } | null>(null)

  // Fetch data from API
  const { data: usersData, isLoading: usersLoading } = useSWR("/api/users?limit=100", fetcher)
  const { data: tracksData, isLoading: tracksLoading } = useSWR("/api/tracks?limit=100", fetcher)
  const { data: artistsData, isLoading: artistsLoading } = useSWR("/api/artists?limit=100", fetcher)
  const { data: albumsData, isLoading: albumsLoading } = useSWR("/api/albums?limit=100", fetcher)
  const { data: genresData, isLoading: genresLoading } = useSWR("/api/genres?limit=100", fetcher)

  const users: User[] = usersData?.data || []
  const tracks: Track[] = tracksData?.data || []
  const artists: Artist[] = artistsData?.data || []
  const albums: Album[] = albumsData?.data || []
  const genres: Genre[] = genresData?.data || []

  const isLoading = usersLoading || tracksLoading || artistsLoading || albumsLoading || genresLoading

  const showToast = useCallback((message: string, type: "success" | "error" | "info" = "success") => {
    setToast({ message, type })
    setTimeout(() => setToast(null), 3000)
  }, [])

  const refreshData = useCallback(() => {
    mutate("/api/users?limit=100")
    mutate("/api/tracks?limit=100")
    mutate("/api/artists?limit=100")
    mutate("/api/albums?limit=100")
    mutate("/api/genres?limit=100")
  }, [])

  // User operations
  const addUser = useCallback(
    async (user: Partial<User>) => {
      try {
        const res = await fetch("/api/users", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(user),
        })
        if (res.ok) {
          mutate("/api/users?limit=100")
          showToast("Utilisateur créé avec succès")
        } else {
          showToast("Erreur lors de la création", "error")
        }
      } catch {
        showToast("Erreur lors de la création", "error")
      }
    },
    [showToast],
  )

  const updateUser = useCallback(
    async (id: string, data: Partial<User>) => {
      try {
        const res = await fetch(`/api/users/${id}`, {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(data),
        })
        if (res.ok) {
          mutate("/api/users?limit=100")
          showToast("Utilisateur mis à jour")
        } else {
          showToast("Erreur lors de la mise à jour", "error")
        }
      } catch {
        showToast("Erreur lors de la mise à jour", "error")
      }
    },
    [showToast],
  )

  const deleteUser = useCallback(
    async (id: string) => {
      try {
        const res = await fetch(`/api/users/${id}`, { method: "DELETE" })
        if (res.ok) {
          mutate("/api/users?limit=100")
          showToast("Utilisateur supprimé")
        } else {
          showToast("Erreur lors de la suppression", "error")
        }
      } catch {
        showToast("Erreur lors de la suppression", "error")
      }
    },
    [showToast],
  )

  const deleteUsers = useCallback(
    async (ids: string[]) => {
      try {
        await Promise.all(ids.map((id) => fetch(`/api/users/${id}`, { method: "DELETE" })))
        mutate("/api/users?limit=100")
        showToast(`${ids.length} utilisateur(s) supprimé(s)`)
      } catch {
        showToast("Erreur lors de la suppression", "error")
      }
    },
    [showToast],
  )

  const suspendUser = useCallback(
    async (id: string) => {
      const user = users.find((u) => u.id === id)
      if (user) {
        await updateUser(id, { is_active: !user.is_active })
        showToast("Statut utilisateur modifié")
      }
    },
    [users, updateUser, showToast],
  )

  // Track operations
  const addTrack = useCallback(
    async (track: Partial<Track>) => {
      try {
        const res = await fetch("/api/tracks", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(track),
        })
        if (res.ok) {
          mutate("/api/tracks?limit=100")
          showToast("Titre ajouté avec succès")
        } else {
          showToast("Erreur lors de l'ajout", "error")
        }
      } catch {
        showToast("Erreur lors de l'ajout", "error")
      }
    },
    [showToast],
  )

  const updateTrack = useCallback(
    async (id: string, data: Partial<Track>) => {
      try {
        const res = await fetch(`/api/tracks/${id}`, {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(data),
        })
        if (res.ok) {
          mutate("/api/tracks?limit=100")
          showToast("Titre mis à jour")
        } else {
          showToast("Erreur lors de la mise à jour", "error")
        }
      } catch {
        showToast("Erreur lors de la mise à jour", "error")
      }
    },
    [showToast],
  )

  const deleteTrack = useCallback(
    async (id: string) => {
      try {
        const res = await fetch(`/api/tracks/${id}`, { method: "DELETE" })
        if (res.ok) {
          mutate("/api/tracks?limit=100")
          showToast("Titre supprimé")
        } else {
          showToast("Erreur lors de la suppression", "error")
        }
      } catch {
        showToast("Erreur lors de la suppression", "error")
      }
    },
    [showToast],
  )

  const deleteTracks = useCallback(
    async (ids: string[]) => {
      try {
        await Promise.all(ids.map((id) => fetch(`/api/tracks/${id}`, { method: "DELETE" })))
        mutate("/api/tracks?limit=100")
        showToast(`${ids.length} titre(s) supprimé(s)`)
      } catch {
        showToast("Erreur lors de la suppression", "error")
      }
    },
    [showToast],
  )

  // Artist operations
  const addArtist = useCallback(
    async (artist: Partial<Artist>) => {
      try {
        const res = await fetch("/api/artists", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(artist),
        })
        if (res.ok) {
          mutate("/api/artists?limit=100")
          showToast("Artiste créé avec succès")
        } else {
          showToast("Erreur lors de la création", "error")
        }
      } catch {
        showToast("Erreur lors de la création", "error")
      }
    },
    [showToast],
  )

  const updateArtist = useCallback(
    async (id: string, data: Partial<Artist>) => {
      try {
        const res = await fetch(`/api/artists/${id}`, {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(data),
        })
        if (res.ok) {
          mutate("/api/artists?limit=100")
          showToast("Artiste mis à jour")
        } else {
          showToast("Erreur lors de la mise à jour", "error")
        }
      } catch {
        showToast("Erreur lors de la mise à jour", "error")
      }
    },
    [showToast],
  )

  const deleteArtist = useCallback(
    async (id: string) => {
      try {
        const res = await fetch(`/api/artists/${id}`, { method: "DELETE" })
        if (res.ok) {
          mutate("/api/artists?limit=100")
          showToast("Artiste supprimé")
        } else {
          showToast("Erreur lors de la suppression", "error")
        }
      } catch {
        showToast("Erreur lors de la suppression", "error")
      }
    },
    [showToast],
  )

  const toggleArtistVerification = useCallback(
    async (id: string) => {
      const artist = artists.find((a) => a.id === id)
      if (artist) {
        await updateArtist(id, { is_verified: !artist.is_verified })
        showToast("Statut de vérification modifié")
      }
    },
    [artists, updateArtist, showToast],
  )

  // Album operations
  const addAlbum = useCallback(
    async (album: Partial<Album>) => {
      try {
        const res = await fetch("/api/albums", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(album),
        })
        if (res.ok) {
          mutate("/api/albums?limit=100")
          showToast("Album créé avec succès")
        } else {
          showToast("Erreur lors de la création", "error")
        }
      } catch {
        showToast("Erreur lors de la création", "error")
      }
    },
    [showToast],
  )

  const updateAlbum = useCallback(
    async (id: string, data: Partial<Album>) => {
      try {
        const res = await fetch(`/api/albums/${id}`, {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(data),
        })
        if (res.ok) {
          mutate("/api/albums?limit=100")
          showToast("Album mis à jour")
        } else {
          showToast("Erreur lors de la mise à jour", "error")
        }
      } catch {
        showToast("Erreur lors de la mise à jour", "error")
      }
    },
    [showToast],
  )

  const deleteAlbum = useCallback(
    async (id: string) => {
      try {
        const res = await fetch(`/api/albums/${id}`, { method: "DELETE" })
        if (res.ok) {
          mutate("/api/albums?limit=100")
          showToast("Album supprimé")
        } else {
          showToast("Erreur lors de la suppression", "error")
        }
      } catch {
        showToast("Erreur lors de la suppression", "error")
      }
    },
    [showToast],
  )

  // Genre operations
  const addGenre = useCallback(
    async (genre: Partial<Genre>) => {
      try {
        const res = await fetch("/api/genres", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(genre),
        })
        if (res.ok) {
          mutate("/api/genres?limit=100")
          showToast("Genre créé avec succès")
        } else {
          showToast("Erreur lors de la création", "error")
        }
      } catch {
        showToast("Erreur lors de la création", "error")
      }
    },
    [showToast],
  )

  const updateGenre = useCallback(
    async (id: string, data: Partial<Genre>) => {
      try {
        const res = await fetch(`/api/genres/${id}`, {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(data),
        })
        if (res.ok) {
          mutate("/api/genres?limit=100")
          showToast("Genre mis à jour")
        } else {
          showToast("Erreur lors de la mise à jour", "error")
        }
      } catch {
        showToast("Erreur lors de la mise à jour", "error")
      }
    },
    [showToast],
  )

  const deleteGenre = useCallback(
    async (id: string) => {
      try {
        const res = await fetch(`/api/genres/${id}`, { method: "DELETE" })
        if (res.ok) {
          mutate("/api/genres?limit=100")
          showToast("Genre supprimé")
        } else {
          showToast("Erreur lors de la suppression", "error")
        }
      } catch {
        showToast("Erreur lors de la suppression", "error")
      }
    },
    [showToast],
  )

  return (
    <AdminContext.Provider
      value={{
        users,
        tracks,
        artists,
        albums,
        genres,
        isLoading,
        addUser,
        updateUser,
        deleteUser,
        deleteUsers,
        suspendUser,
        addTrack,
        updateTrack,
        deleteTrack,
        deleteTracks,
        addArtist,
        updateArtist,
        deleteArtist,
        toggleArtistVerification,
        addAlbum,
        updateAlbum,
        deleteAlbum,
        addGenre,
        updateGenre,
        deleteGenre,
        showToast,
        toast,
        refreshData,
      }}
    >
      {children}
      {toast && (
        <div
          className={`fixed bottom-4 right-4 z-50 px-4 py-3 rounded-lg shadow-lg flex items-center gap-2 animate-in slide-in-from-bottom-4 ${
            toast.type === "success" ? "bg-green-600" : toast.type === "error" ? "bg-red-600" : "bg-blue-600"
          } text-white`}
        >
          {toast.type === "success" && <span>✓</span>}
          {toast.type === "error" && <span>✕</span>}
          {toast.type === "info" && <span>ℹ</span>}
          {toast.message}
        </div>
      )}
    </AdminContext.Provider>
  )
}

export function useAdmin() {
  const context = useContext(AdminContext)
  if (!context) {
    throw new Error("useAdmin must be used within an AdminProvider")
  }
  return context
}
