import { useState, useEffect, useCallback } from 'react'
import { dataService } from '../data/dataService'
import type { Workout, Trainer, Collection, Program } from '../types'

export function useWorkouts() {
  const [workouts, setWorkouts] = useState<Workout[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  const fetchWorkouts = useCallback(async () => {
    try {
      setLoading(true)
      const data = await dataService.getAllWorkouts()
      setWorkouts(data)
      setError(null)
    } catch (err) {
      setError(err as Error)
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    let mounted = true

    async function load() {
      try {
        setLoading(true)
        const data = await dataService.getAllWorkouts()
        if (mounted) {
          setWorkouts(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [])

  return { workouts, loading, error, refetch: fetchWorkouts }
}

export function useWorkout(id: string | undefined) {
  const [workout, setWorkout] = useState<Workout | undefined>()
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    let mounted = true

    async function load() {
      if (!id) {
        setLoading(false)
        return
      }

      try {
        setLoading(true)
        const data = await dataService.getWorkoutById(id)
        if (mounted) {
          setWorkout(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [id])

  return { workout, loading, error }
}

export function useWorkoutsByCategory(category: string) {
  const [workouts, setWorkouts] = useState<Workout[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    let mounted = true

    async function load() {
      try {
        setLoading(true)
        const data = await dataService.getWorkoutsByCategory(category)
        if (mounted) {
          setWorkouts(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [category])

  return { workouts, loading, error }
}

export function useTrainers() {
  const [trainers, setTrainers] = useState<Trainer[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  const fetchTrainers = useCallback(async () => {
    try {
      setLoading(true)
      const data = await dataService.getAllTrainers()
      setTrainers(data)
      setError(null)
    } catch (err) {
      setError(err as Error)
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    let mounted = true

    async function load() {
      try {
        setLoading(true)
        const data = await dataService.getAllTrainers()
        if (mounted) {
          setTrainers(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [])

  return { trainers, loading, error, refetch: fetchTrainers }
}

export function useTrainer(id: string | undefined) {
  const [trainer, setTrainer] = useState<Trainer | undefined>()
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    let mounted = true

    async function load() {
      if (!id) {
        setLoading(false)
        return
      }

      try {
        setLoading(true)
        const data = await dataService.getTrainerById(id)
        if (mounted) {
          setTrainer(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [id])

  return { trainer, loading, error }
}

export function useCollections() {
  const [collections, setCollections] = useState<Collection[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  const fetchCollections = useCallback(async () => {
    try {
      setLoading(true)
      const data = await dataService.getAllCollections()
      setCollections(data)
      setError(null)
    } catch (err) {
      setError(err as Error)
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    let mounted = true

    async function load() {
      try {
        setLoading(true)
        const data = await dataService.getAllCollections()
        if (mounted) {
          setCollections(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [])

  return { collections, loading, error, refetch: fetchCollections }
}

export function useCollection(id: string | undefined) {
  const [collection, setCollection] = useState<Collection | undefined>()
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    let mounted = true

    async function load() {
      if (!id) {
        setLoading(false)
        return
      }

      try {
        setLoading(true)
        const data = await dataService.getCollectionById(id)
        if (mounted) {
          setCollection(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [id])

  return { collection, loading, error }
}

export function usePrograms() {
  const [programs, setPrograms] = useState<Program[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    let mounted = true

    async function load() {
      try {
        setLoading(true)
        const data = await dataService.getAllPrograms()
        if (mounted) {
          setPrograms(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [])

  return { programs, loading, error }
}

export function useFeaturedWorkouts() {
  const [workouts, setWorkouts] = useState<Workout[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    let mounted = true

    async function load() {
      try {
        setLoading(true)
        const data = await dataService.getFeaturedWorkouts()
        if (mounted) {
          setWorkouts(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [])

  return { workouts, loading, error }
}

export function useWorkoutsByTrainer(trainerId: string) {
  const [workouts, setWorkouts] = useState<Workout[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    let mounted = true

    async function load() {
      try {
        setLoading(true)
        const data = await dataService.getWorkoutsByTrainer(trainerId)
        if (mounted) {
          setWorkouts(data)
          setError(null)
        }
      } catch (err) {
        if (mounted) {
          setError(err as Error)
        }
      } finally {
        if (mounted) {
          setLoading(false)
        }
      }
    }

    load()
    return () => { mounted = false }
  }, [trainerId])

  return { workouts, loading, error }
}
