import React, { useEffect, useState } from 'react'
import { View, Text, StyleSheet, FlatList, TouchableOpacity, ActivityIndicator } from 'react-native'
import { withObservables } from '@nozbe/watermelondb/react'
import { Observable } from 'rxjs'
import { map, switchMap } from 'rxjs/operators'
import { Q } from '@nozbe/watermelondb'

import { database } from '../../src/db/index'
import UserChallenge from '../../src/db/models/UserChallenge'
import DailyProgress from '../../src/db/models/DailyProgress'
import TaskCompletion from '../../src/db/models/TaskCompletion'
import { getActiveUserChallenge, getOrCreateDailyProgress, getOrCreateTaskCompletions, toggleTaskCompletion } from '../../src/utils/progress'
import { Colors } from '../../constants/theme'
import { IconSymbol } from '../../components/ui/icon-symbol'

interface TaskItemProps {
  taskCompletion: TaskCompletion
  onToggle: (task: TaskCompletion, isCompleted: boolean) => void
}

const TaskItem = withObservables(['taskCompletion'], ({ taskCompletion }) => ({
  taskCompletion,
  requirement: taskCompletion.requirement,
}))(({ taskCompletion, requirement, onToggle }: TaskItemProps & { requirement: any }) => {
  const isCompleted = taskCompletion.completedAt > 0

  return (
    <TouchableOpacity 
      style={styles.taskItem} 
      onPress={() => onToggle(taskCompletion, !isCompleted)}
    >
      <View style={[styles.checkbox, isCompleted && styles.checkboxChecked]}>
        {isCompleted && <IconSymbol name="checkmark" size={16} color="white" />}
      </View>
      <View style={styles.taskContent}>
        <Text style={[styles.taskTitle, isCompleted && styles.taskTitleCompleted]}>
          {requirement.title}
        </Text>
        {requirement.description && (
          <Text style={styles.taskDescription}>{requirement.description}</Text>
        )}
      </View>
    </TouchableOpacity>
  )
})

interface ProgressScreenProps {
  userChallenge: UserChallenge | null
  dailyProgress: DailyProgress | null
  taskCompletions: TaskCompletion[]
}

const ProgressScreen = ({ userChallenge, dailyProgress, taskCompletions }: ProgressScreenProps) => {
  const [error, setError] = useState<string | null>(null)

  console.log('ProgressScreen: render', {
    hasUserChallenge: !!userChallenge,
    hasDailyProgress: !!dailyProgress,
    taskCompletionsCount: taskCompletions.length,
    error
  })
  
  useEffect(() => {
    const ensureProgress = async () => {
      if (userChallenge) {
        try {
          setError(null)
          console.log('ProgressScreen: ensuring progress for challenge', userChallenge.id)
          const progress = await getOrCreateDailyProgress(userChallenge)
          console.log('ProgressScreen: daily progress obtained', progress.id)
          await getOrCreateTaskCompletions(progress)
          console.log('ProgressScreen: task completions ensured')
        } catch (e: any) {
          console.error('Error ensuring daily progress:', e)
          setError(e.message || 'Failed to load progress')
        }
      }
    }
    
    ensureProgress()
  }, [userChallenge])

  if (!userChallenge) {
    return (
      <View style={styles.centered}>
        <Text style={styles.emptyText}>No active challenge found.</Text>
        <Text style={styles.subText}>Go to the Explore tab to start a challenge!</Text>
      </View>
    )
  }

  if (error) {
    return (
      <View style={styles.centered}>
        <Text style={styles.emptyText}>Something went wrong</Text>
        <Text style={styles.subText}>{error}</Text>
        <TouchableOpacity onPress={() => setError(null)} style={{ marginTop: 20, padding: 10, backgroundColor: Colors.light.tint, borderRadius: 8 }}>
            <Text style={{ color: 'white', fontWeight: 'bold' }}>Retry</Text>
        </TouchableOpacity>
      </View>
    )
  }

  if (!dailyProgress) {
     // If we have a user challenge but no daily progress yet, it might be creating it.
     // However, if it takes too long or fails, we should probably show something else or retry.
     // For now, let's just log that we are waiting.
     console.log('ProgressScreen: waiting for dailyProgress')
     return (
        <View style={styles.centered}>
            <ActivityIndicator size="large" color={Colors.light.tint} />
            <Text style={{ marginTop: 10 }}>Loading today{`'`}s progress...</Text>
        </View>
     )
  }

  const completedCount = taskCompletions.filter(t => t.completedAt > 0).length
  const totalCount = taskCompletions.length
  const progressPercentage = totalCount > 0 ? completedCount / totalCount : 0

  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.challengeName}>{userChallenge.challenge.name}</Text>
        <Text style={styles.dayText}>Day {dailyProgress.dayNumber}</Text>
      </View>

      <View style={styles.progressContainer}>
        <View style={styles.progressBarBackground}>
          <View style={[styles.progressBarFill, { width: `${progressPercentage * 100}%` }]} />
        </View>
        <Text style={styles.progressText}>
          {completedCount} of {totalCount} tasks completed
        </Text>
      </View>

      {progressPercentage === 1 && (
        <View style={styles.congratsContainer}>
            <IconSymbol name="star.fill" size={40} color="#FFD700" />
            <Text style={styles.congratsText}>Day Complete! Great Job!</Text>
        </View>
      )}

      <FlatList
        data={taskCompletions}
        keyExtractor={item => item.id}
        renderItem={({ item }) => (
          <TaskItem
            taskCompletion={item}
            onToggle={toggleTaskCompletion}
          />
        )}
        contentContainerStyle={styles.listContent}
      />
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
  },
  centered: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  header: {
    padding: 20,
    backgroundColor: 'white',
    borderBottomWidth: 1,
    borderBottomColor: '#e0e0e0',
  },
  challengeName: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#333',
  },
  dayText: {
    fontSize: 18,
    color: '#666',
    marginTop: 4,
  },
  progressContainer: {
    padding: 20,
    backgroundColor: 'white',
    marginBottom: 10,
  },
  progressBarBackground: {
    height: 10,
    backgroundColor: '#e0e0e0',
    borderRadius: 5,
    overflow: 'hidden',
  },
  progressBarFill: {
    height: '100%',
    backgroundColor: Colors.light.tint,
  },
  progressText: {
    marginTop: 8,
    textAlign: 'right',
    color: '#666',
  },
  listContent: {
    padding: 16,
  },
  taskItem: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: 'white',
    padding: 16,
    borderRadius: 12,
    marginBottom: 12,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.05,
    shadowRadius: 4,
    elevation: 2,
  },
  checkbox: {
    width: 24,
    height: 24,
    borderRadius: 12,
    borderWidth: 2,
    borderColor: Colors.light.tint,
    marginRight: 16,
    justifyContent: 'center',
    alignItems: 'center',
  },
  checkboxChecked: {
    backgroundColor: Colors.light.tint,
  },
  taskContent: {
    flex: 1,
  },
  taskTitle: {
    fontSize: 16,
    fontWeight: '600',
    color: '#333',
  },
  taskTitleCompleted: {
    textDecorationLine: 'line-through',
    color: '#999',
  },
  taskDescription: {
    fontSize: 14,
    color: '#666',
    marginTop: 2,
  },
  emptyText: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#333',
    marginBottom: 8,
  },
  subText: {
    fontSize: 16,
    color: '#666',
    textAlign: 'center',
  },
  congratsContainer: {
    backgroundColor: '#E8F5E9',
    margin: 20,
    marginTop: 0,
    padding: 15,
    borderRadius: 12,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 1,
    borderColor: '#4CAF50',
  },
  congratsText: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#2E7D32',
    marginLeft: 10,
  },
})

const enhance = withObservables([], () => {
  // We need to observe the active user challenge and today's progress
  // This is a bit complex because we need to chain observables
  
  // 1. Get active user challenge
  const userChallenge$ = database.get<UserChallenge>('user_challenges')
    .query(
        Q.where('status', 'active')
    )
    .observeWithColumns(['status'])
    .pipe(
      map((challenges: UserChallenge[]) => challenges.length > 0 ? challenges[0] : null)
    )

  return {
    userChallenge: userChallenge$,
    dailyProgress: userChallenge$.pipe(
      switchMap((uc: UserChallenge | null): Observable<DailyProgress | null> => {
        if (!uc) return new Observable<DailyProgress | null>(observer => observer.next(null))
        
        const today = new Date()
        today.setHours(0,0,0,0)
        const todayTs = today.getTime()

        return database.get<DailyProgress>('daily_progress')
            .query(
                Q.where('user_challenge_id', uc.id),
                Q.where('progress_date', todayTs)
            )
            .observe()
            .pipe(
                map(progresses => progresses.length > 0 ? progresses[0] : null)
            )
      })
    ),
    taskCompletions: userChallenge$.pipe(
        switchMap((uc: UserChallenge | null): Observable<TaskCompletion[]> => {
            if (!uc) return new Observable<TaskCompletion[]>(observer => { observer.next([]); observer.complete() })
            
            const today = new Date()
            today.setHours(0,0,0,0)
            const todayTs = today.getTime()

            return database.get<DailyProgress>('daily_progress')
                .query(
                    Q.where('user_challenge_id', uc.id),
                    Q.where('progress_date', todayTs)
                )
                .observe()
                .pipe(
                    switchMap((progresses: DailyProgress[]): Observable<TaskCompletion[]> => {
                        const todayProgress = progresses.length > 0 ? progresses[0] : null
                        if (!todayProgress) return new Observable<TaskCompletion[]>(observer => { observer.next([]); observer.complete() })
                        
                        return todayProgress.taskCompletions.observe()
                    })
                )
        })
    ) as Observable<TaskCompletion[]>
  }
})

export default enhance(ProgressScreen)