import { useState, useEffect } from 'react'
import CombatView from './CombatView'
import { CombatState, CombatLogEntry, Profile, Equipment, PlayerState } from './types'
import api from '../../services/api'
import './CombatEffects.css'

interface CombatProps {
    combatState: CombatState
    profile: Profile | null
    playerState: PlayerState | null
    equipment: Equipment
    onCombatAction: (action: string) => Promise<any>
    onExitCombat: () => void
    onPvPAction: (action: string) => Promise<any>
    onExitPvPCombat: () => void
    combatLog: CombatLogEntry[]
    addCombatLogEntry: (entry: CombatLogEntry) => void
    updatePlayerState: (state: PlayerState) => void
    updateCombatState: (state: CombatState) => void
}

const Combat = ({
    combatState,
    profile,
    playerState,
    equipment,
    onCombatAction,
    onExitCombat,
    onPvPAction,
    onExitPvPCombat,
    combatLog,
    addCombatLogEntry,
    updatePlayerState,
    updateCombatState
}: CombatProps) => {
    // Local state for visual effects and logic
    const [shake, setShake] = useState(false)
    const [flash, setFlash] = useState(false)
    const [floatingTexts, setFloatingTexts] = useState<{ id: number, text: string, x: number, y: number, type: 'damage-player' | 'damage-enemy' | 'damage-player-dealt' | 'heal' }[]>([])
    const [processing, setProcessing] = useState(false)
    const [pvpTimer, setPvpTimer] = useState<number | null>(null)
    const [localEnemyTurnMessage, setLocalEnemyTurnMessage] = useState('')

    // Temporary HP state to delay player HP updates during enemy turn
    const [tempPlayerHP, setTempPlayerHP] = useState<number | null>(null)

    // Turn timer state for PvE combat
    const [turnTimeRemaining, setTurnTimeRemaining] = useState<number | null>(null)

    // PvP Timer Effect
    useEffect(() => {
        if (combatState.is_pvp && combatState.pvp_combat) {
            // Always set timer from server value
            setPvpTimer(combatState.pvp_combat.time_remaining)

            // Run countdown locally for smooth UI
            const interval = setInterval(() => {
                setPvpTimer(prev => (prev && prev > 0 ? prev - 1 : 0))
            }, 1000)
            return () => clearInterval(interval)
        } else {
            setPvpTimer(null)
        }
    }, [combatState.is_pvp, combatState.pvp_combat])

    // PvE Timer Effect - Update from server-calculated time
    // Reset timer whenever turn_time_remaining changes from server
    useEffect(() => {
        if (!combatState.is_pvp && combatState.combat?.turn === 'player' && combatState.combat?.turn_time_remaining !== undefined) {
            // Always set the timer from server value to ensure it resets after each turn
            setTurnTimeRemaining(combatState.combat.turn_time_remaining)
        } else {
            setTurnTimeRemaining(null)
        }
    }, [combatState.is_pvp, combatState.combat?.turn, combatState.combat?.turn_time_remaining])

    // PvE Timer Countdown Effect - Decrement locally for smooth UI
    useEffect(() => {
        if (turnTimeRemaining !== null && turnTimeRemaining > 0) {
            const interval = setInterval(() => {
                setTurnTimeRemaining(prev => prev !== null && prev > 0 ? prev - 1 : 0)
            }, 1000)
            return () => clearInterval(interval)
        }
    }, [turnTimeRemaining])

    // PvE Polling Effect - Poll when timeout is imminent (< 30s) to catch background task
    useEffect(() => {
        if (!combatState.is_pvp && turnTimeRemaining !== null && turnTimeRemaining < 30 && turnTimeRemaining >= 0) {
            const pollInterval = setInterval(async () => {
                try {
                    // Fetch updated combat state from API
                    const response = await api.get('/api/game/combat')
                    if (response.data.in_combat && response.data.combat) {
                        // Update combat state if turn changed (background task processed timeout)
                        if (response.data.combat.turn !== combatState.combat?.turn) {
                            updateCombatState({
                                ...combatState,
                                combat: response.data.combat
                            })
                        }
                    }
                } catch (error) {
                    console.error('Failed to poll combat state:', error)
                }
            }, 10000) // Poll every 10 seconds

            return () => clearInterval(pollInterval)
        }
    }, [turnTimeRemaining, combatState, updateCombatState])

    const addFloatingText = (text: string, x: number, y: number, type: 'damage-player' | 'damage-enemy' | 'damage-player-dealt' | 'heal') => {
        const id = Date.now() + Math.random()
        setFloatingTexts(prev => [...prev, { id, text, x, y, type }])
        setTimeout(() => {
            setFloatingTexts(prev => prev.filter(ft => ft.id !== id))
        }, 2500)
    }

    const handlePvEAction = async (action: string) => {
        if (processing) return
        setProcessing(true)

        try {
            const data = await onCombatAction(action)
            const now = new Date()
            const timeStr = now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })

            // Parse messages
            const messages = data.message.split('\n').filter((m: string) => m.trim())

            // Handle failed flee special case - split combined message
            const processedMessages: string[] = []
            messages.forEach((msg: string) => {
                // Check if message contains both flee failure and enemy attack
                const fleeFailMatch = msg.match(/^(Failed to flee!)\s+(.+)$/)
                if (fleeFailMatch) {
                    processedMessages.push(fleeFailMatch[1]) // "Failed to flee!"
                    processedMessages.push(fleeFailMatch[2]) // Enemy attack message
                } else {
                    processedMessages.push(msg)
                }
            })

            const playerMessages = processedMessages.filter((msg: string) =>
                msg.includes('You ') || msg.includes('Your ') || msg === 'Failed to flee!'
            )
            const enemyMessages = processedMessages.filter((msg: string) =>
                msg !== 'Failed to flee!' &&
                (msg.includes('attacks') || msg.includes('hits') || msg.includes('misses') || msg.includes('The '))
            )

            // Check if this is a failed flee attempt
            const isFailedFlee = playerMessages.some(msg => msg === 'Failed to flee!')

            // 1. Immediate Player Feedback
            playerMessages.forEach((msg: string) => {
                addCombatLogEntry({ time: timeStr, message: msg, isPlayer: true })

                // Only show attack animations for actual attacks, not flee failures
                if (msg !== 'Failed to flee!') {
                    const damageMatch = msg.match(/(\d+) damage/)
                    if (damageMatch) {
                        addFloatingText(damageMatch[1], 50, 30, 'damage-player-dealt') // White text on enemy
                        setFlash(true)
                        setTimeout(() => setFlash(false), 300)
                    }
                }
            })

            // Update Enemy HP immediately
            if (data.combat && !data.combat_over) {
                updateCombatState({
                    ...combatState,
                    combat: {
                        ...combatState.combat,
                        npc_hp: data.combat.npc_hp,
                        turn: data.combat.turn,
                        turn_time_remaining: data.combat.turn_time_remaining,
                        round: data.combat.round
                    }
                })

                // Store current player HP to prevent it from updating during enemy turn
                if (data.player && playerState) {
                    setTempPlayerHP(playerState.health)
                }
            }

            // 2. Enemy Turn Delay (including failed flee)
            if ((enemyMessages.length > 0 || isFailedFlee) && !data.combat_over) {
                setLocalEnemyTurnMessage(isFailedFlee ? "🗡️ Enemy's turn..." : "🗡️ Enemy's turn...")

                await new Promise(resolve => setTimeout(resolve, 2000))

                enemyMessages.forEach((msg: string) => {
                    addCombatLogEntry({ time: timeStr, message: msg, isPlayer: false })

                    const damageMatch = msg.match(/(\d+) damage/)
                    if (damageMatch) {
                        addFloatingText(damageMatch[1], 50, 50, 'damage-player') // Red text over player position
                        setShake(true)
                        setTimeout(() => setShake(false), 500)
                    }
                })

                setLocalEnemyTurnMessage('')

                // Update Player HP after delay completes
                if (data.player && playerState) {
                    setTempPlayerHP(null) // Clear temp HP
                    updatePlayerState({
                        ...playerState,
                        health: data.player.hp,
                        max_health: data.player.max_hp ?? playerState.max_health
                    })
                }
            } else if (data.combat_over) {
                // Combat ended (e.g. player won or fled)
                const playerFled = data.message.toLowerCase().includes('fled') ||
                    data.message.toLowerCase().includes('escape') ||
                    data.player_fled === true

                updateCombatState({
                    ...combatState,
                    combat_over: true,
                    player_won: data.player_won || false,
                    player_fled: playerFled,
                    combat: {
                        ...combatState.combat,
                        npc_hp: data.player_won ? 0 : (data.combat?.npc_hp ?? combatState.combat.npc_hp)
                    }
                })
                // Update player state immediately if combat is over
                setTempPlayerHP(null) // Clear temp HP
                if (data.player && playerState) {
                    updatePlayerState({
                        ...playerState,
                        health: data.player.hp,
                        max_health: data.player.max_hp ?? playerState.max_health
                    })
                }
            }

        } catch (error) {
            console.error('Combat action failed:', error)
        } finally {
            setProcessing(false)
        }
    }

    const handlePvPActionLocal = async (action: string) => {
        if (processing) return
        setProcessing(true)

        try {
            // Call the parent handler (which calls API)
            // Note: onPvPAction in Game.tsx currently returns void, but we might need the response
            // We'll modify onPvPAction to return the response or we'll rely on the websocket update for state
            // BUT for animations we need the immediate response if possible, OR we parse the websocket message?
            // The user request says "The timer is also not updating correctly, it should grab the latest data from the websocket update or from the action call."
            // So let's assume onPvPAction CAN return data if we await it.
            // Checking Game.tsx: onPvPAction calls api.post and sets message. It doesn't return data.
            // We need to modify Game.tsx to return the data too? 
            // Actually, let's just trigger the action and let the websocket handle the state update, 
            // BUT for "floating text for damage", we usually get that from the immediate response in PvE.
            // In PvP, the response might contain the damage info.

            // Let's assume onPvPAction returns the response data now (we'll fix Game.tsx if needed, or just use what we have)
            // Wait, Game.tsx onPvPAction is:
            // onPvPAction={async (action: string) => {
            //   try {
            //     const response = await api.post('/api/game/pvp/action', { action })
            //     actions.setMessage(response.data.message || 'Action performed!')
            //     await actions.fetchGameData()
            //   } ...
            // }}
            // It doesn't return the data to the caller.

            // We will modify Combat.tsx to accept a promise that returns data, OR we modify Game.tsx to return it.
            // For now, let's just call it and see if we can parse the message from the state update? 
            // No, animations need to happen NOW.

            // Let's change onPvPAction prop signature in Combat.tsx to return Promise<any>
            // and update Game.tsx to return the response.data.

            const data = await onPvPAction(action)

            if (data) {
                const now = new Date()
                const timeStr = now.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })

                // Parse message for damage
                // Example: "You attacked X for 10 damage!"
                const msg = data.message || ''
                addCombatLogEntry({ time: timeStr, message: msg, isPlayer: true })

                const damageMatch = msg.match(/(\d+) damage/)
                if (damageMatch) {
                    addFloatingText(damageMatch[1], 50, 30, 'damage-player-dealt')
                    setFlash(true)
                    setTimeout(() => setFlash(false), 300)
                }

                // If we got hit back immediately (e.g. recoil? or just turn end?)
                // Usually PvP is turn based, so we wait for opponent.
            }

        } catch (error) {
            console.error('PvP action failed:', error)
        } finally {
            setProcessing(false)
        }
    }

    return (
        <div className={`combat-container ${shake ? 'shake-effect' : ''}`}>
            <CombatView
                combatState={combatState}
                combatLog={combatLog}
                profile={profile}
                playerState={tempPlayerHP !== null && playerState ? {
                    ...playerState,
                    health: tempPlayerHP
                } : playerState}
                equipment={equipment}
                enemyName={combatState.combat?.npc_name || 'Enemy'}
                enemyImage={combatState.combat?.npc_image || combatState.combat_image || ''}
                enemyTurnMessage={localEnemyTurnMessage}
                pvpTimeRemaining={pvpTimer}
                turnTimeRemaining={turnTimeRemaining}
                onCombatAction={handlePvEAction}
                onFlee={async () => handlePvEAction('flee')}
                onPvPAction={handlePvPActionLocal}
                onExitCombat={onExitCombat}
                onExitPvPCombat={onExitPvPCombat}
                flashEnemy={flash}
                buttonsDisabled={processing}
                floatingTexts={floatingTexts}
            />
        </div>
    )
}

export default Combat
