/**
 * Progress Store — Simplified
 *
 * Unique source de vérité pour le progrès utilisateur :
 * - Streak (current + longest, basé sur jours uniques)
 * - History (capped à 30 dernières séances, pour perf mobile)
 * - Completed programs (set d'IDs)
 * - Weekly count (séances cette semaine)
 *
 * Remplace activityStore + workoutProgramStore.
 */

import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { useUserStore } from './userStore'
import { syncWorkoutSession } from '@/src/shared/services/sync'

// ─── Types ──────────────────────────────────────────────────────

export interface ProgramSession {
  /** Program ID (e.g. "wp-upper-beginner-01") */
  programId: string
  /** Epoch ms */
  completedAt: number
  /** Total duration in seconds */
  durationSeconds: number
  /** Body zone: "upper" | "lower" | "full" */
  bodyZone: string
  /** Level: "Beginner" | "Intermediate" | "Advanced" */
  level: string
}

interface ProgressState {
  history: ProgramSession[]
  completedProgramIds: string[]
  streak: { current: number; longest: number }

  // Actions
  completeProgram: (session: ProgramSession) => Promise<void>
  resetProgress: () => void

  // Getters
  isProgramCompleted: (programId: string) => boolean
  getCompletedCount: () => number
  getWeeklyCount: () => number
  getStreak: () => { current: number; longest: number }
}

// ─── Helpers ────────────────────────────────────────────────────

const HISTORY_CAP = 30
const MS_PER_DAY = 86_400_000

function toDateKey(timestamp: number): string {
  return new Date(timestamp).toISOString().split('T')[0]
}

function computeStreak(history: ProgramSession[]): { current: number; longest: number } {
  if (history.length === 0) return { current: 0, longest: 0 }

  const uniqueDays = Array.from(new Set(history.map((s) => toDateKey(s.completedAt)))).sort().reverse()
  const today = toDateKey(Date.now())
  const yesterday = toDateKey(Date.now() - MS_PER_DAY)
  const isActive = uniqueDays[0] === today || uniqueDays[0] === yesterday

  const longest = computeLongest(uniqueDays)
  if (!isActive) return { current: 0, longest }

  let current = 1
  for (let i = 0; i < uniqueDays.length - 1; i++) {
    const diff = new Date(uniqueDays[i]).getTime() - new Date(uniqueDays[i + 1]).getTime()
    if (diff <= MS_PER_DAY) current++
    else break
  }
  return { current, longest: Math.max(current, longest) }
}

function computeLongest(sortedDays: string[]): number {
  if (sortedDays.length === 0) return 0
  let longest = 1
  let run = 1
  for (let i = 0; i < sortedDays.length - 1; i++) {
    const diff = new Date(sortedDays[i]).getTime() - new Date(sortedDays[i + 1]).getTime()
    if (diff <= MS_PER_DAY) {
      run++
      longest = Math.max(longest, run)
    } else {
      run = 1
    }
  }
  return longest
}

function countThisWeek(history: ProgramSession[]): number {
  const now = new Date()
  const startOfWeek = new Date(now)
  startOfWeek.setDate(now.getDate() - now.getDay())
  startOfWeek.setHours(0, 0, 0, 0)
  const cutoff = startOfWeek.getTime()
  return history.filter((s) => s.completedAt >= cutoff).length
}

// ─── Store ──────────────────────────────────────────────────────

export const useProgressStore = create<ProgressState>()(
  persist(
    (set, get) => ({
      history: [],
      completedProgramIds: [],
      streak: { current: 0, longest: 0 },

      completeProgram: async (session) => {
        const existing = get()
        const newHistory = [session, ...existing.history].slice(0, HISTORY_CAP)
        const newCompleted = existing.completedProgramIds.includes(session.programId)
          ? existing.completedProgramIds
          : [...existing.completedProgramIds, session.programId]
        const newStreak = computeStreak(newHistory)

        set({
          history: newHistory,
          completedProgramIds: newCompleted,
          streak: newStreak,
        })

        // Sync to Supabase if premium + synced
        const userStore = useUserStore.getState()
        const isPremium = userStore.profile.subscription !== 'free'
        if (userStore.profile.syncStatus === 'synced') {
          await syncWorkoutSession({
            workoutId: session.programId,
            completedAt: new Date(session.completedAt).toISOString(),
            durationSeconds: session.durationSeconds,
            caloriesBurned: 0,
            feelingRating: undefined,
          })
        } else if (userStore.profile.syncStatus === 'never-synced' && isPremium) {
          userStore.setPromptPending()
        }
      },

      resetProgress: () => {
        set({ history: [], completedProgramIds: [], streak: { current: 0, longest: 0 } })
      },

      isProgramCompleted: (programId) => get().completedProgramIds.includes(programId),
      getCompletedCount: () => get().completedProgramIds.length,
      getWeeklyCount: () => countThisWeek(get().history),
      getStreak: () => get().streak,
    }),
    {
      name: 'tabatago-progress',
      storage: createJSONStorage(() => AsyncStorage),
      version: 1,
    },
  ),
)
