import { useCallback, useEffect, useMemo, useState } from 'react'
import '@fortawesome/fontawesome-free/css/all.min.css'
import './App.css'

const API_BASE_URL = (import.meta.env.VITE_API_BASE_URL || '/api').replace(/\/$/, '')
const ADMIN_URL = import.meta.env.VITE_ADMIN_URL || 'http://localhost:5002/admin/login'
const DEFAULT_FORM = Object.freeze({
  name: '',
  message: '',
  gender: '保密',
  qq: '',
})

const BACKGROUND_IMAGES = Array.from({ length: 29 }, (_, index) => `/background/image${index + 1}.png`)

const formatCount = (value) => {
  const num = typeof value === 'number' ? value : Number(value || 0)
  return Number.isNaN(num) ? 0 : num
}

function App() {
  const [formData, setFormData] = useState({ ...DEFAULT_FORM })
  const [limits, setLimits] = useState({ name: 7, message: 100 })
  const [stats, setStats] = useState({ total_bottles: 0 })
  const [motto, setMotto] = useState('载入中...')
  const [throwStatus, setThrowStatus] = useState('')
  const [pickupStatus, setPickupStatus] = useState('')
  const [currentBottle, setCurrentBottle] = useState(null)
  const [cooldowns, setCooldowns] = useState({ throw: 0, pickup: 0 })
  const [loadingAction, setLoadingAction] = useState({ throw: false, pickup: false })
  const [reactionDisabled, setReactionDisabled] = useState(false)
  const isThrowing = loadingAction.throw
  const isPicking = loadingAction.pickup

  const randomBackground = useMemo(() => {
    if (!BACKGROUND_IMAGES.length) {
      return ''
    }
    const index = Math.floor(Math.random() * BACKGROUND_IMAGES.length)
    return BACKGROUND_IMAGES[index]
  }, [])

  useEffect(() => {
    if (randomBackground) {
      document.documentElement.style.setProperty('--app-background-image', `url(${randomBackground})`)
    }
  }, [randomBackground])

  const startCooldown = useCallback((type, seconds = 5) => {
    const duration = Math.max(1, Math.ceil(seconds))
    setCooldowns((prev) => ({ ...prev, [type]: duration }))
  }, [])

  useEffect(() => {
    const timer = setInterval(() => {
      setCooldowns((prev) => {
        const next = {
          throw: prev.throw > 0 ? prev.throw - 1 : 0,
          pickup: prev.pickup > 0 ? prev.pickup - 1 : 0,
        }
        if (next.throw === prev.throw && next.pickup === prev.pickup) {
          return prev
        }
        return next
      })
    }, 1000)
    return () => clearInterval(timer)
  }, [])

  const fetchConfig = useCallback(async () => {
    try {
      const response = await fetch(`${API_BASE_URL}/config`)
      const data = await response.json()
      if (data.success && data.config) {
        setLimits({
          name: data.config.name_limit ?? 7,
          message: data.config.message_limit ?? 100,
        })
      }
    } catch (error) {
      console.error('Failed to fetch config', error)
    }
  }, [])

  const fetchStats = useCallback(async () => {
    try {
      const response = await fetch(`${API_BASE_URL}/stats`)
      const data = await response.json()
      if (data.success && data.stats) {
        setStats(data.stats)
      }
    } catch (error) {
      console.error('Failed to fetch stats', error)
    }
  }, [])

  const fetchMotto = useCallback(async () => {
    try {
      const response = await fetch(`${API_BASE_URL}/motto`)
      const data = await response.json()
      if (data.success) {
        setMotto(data.motto)
      }
    } catch (error) {
      console.error('Failed to fetch motto', error)
      setMotto('良言一句三冬暖，恶语伤人六月寒')
    }
  }, [])

  useEffect(() => {
    fetchConfig()
    fetchStats()
    fetchMotto()
  }, [fetchConfig, fetchStats, fetchMotto])

  const handleInputChange = useCallback((event) => {
    const { name, value } = event.target
    if (name === 'qq' && value && /[^0-9]/.test(value)) {
      return
    }
    setFormData((prev) => ({ ...prev, [name]: value }))
  }, [])

  const resetForm = useCallback(() => {
    setFormData({ ...DEFAULT_FORM })
  }, [])

  const handleThrowSubmit = useCallback(
    async (event) => {
      event.preventDefault()
      if (cooldowns.throw > 0 || isThrowing) {
        return
      }

      setLoadingAction((prev) => ({ ...prev, throw: true }))
      setThrowStatus('正在扔瓶子...')

      try {
        const response = await fetch(`${API_BASE_URL}/throw`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            name: formData.name,
            message: formData.message,
            gender: formData.gender,
            qq: formData.qq,
          }),
        })

        const data = await response.json()
        if (response.ok && data.success) {
          setThrowStatus('瓶子已成功扔出！祝你好运~')
          resetForm()
          fetchStats()
          startCooldown('throw', 5)
        } else {
          const waitTime = data.wait_time ?? 0
          setThrowStatus(`出错了: ${data.error || data.message || '未知错误'}`)
          if (waitTime) {
            startCooldown('throw', waitTime)
          }
        }
      } catch (error) {
        console.error('Throw request failed', error)
        setThrowStatus('请求失败，请检查网络连接。')
      } finally {
        setLoadingAction((prev) => ({ ...prev, throw: false }))
      }
    },
    [cooldowns.throw, isThrowing, formData, fetchStats, resetForm, startCooldown],
  )

  const handlePickup = useCallback(async () => {
    if (cooldowns.pickup > 0 || isPicking) {
      return
    }
    setLoadingAction((prev) => ({ ...prev, pickup: true }))
    setPickupStatus('正在打捞瓶子...')

    try {
      const response = await fetch(`${API_BASE_URL}/pickup`)
      const data = await response.json()
      if (response.ok && data.success && data.bottle) {
        setCurrentBottle(data.bottle)
        setReactionDisabled(false)
        setPickupStatus('捡到了一个瓶子！缘分来了~')
        startCooldown('pickup', 5)
      } else {
        setCurrentBottle(null)
        const waitTime = data.wait_time ?? 0
        setPickupStatus(data.message || data.error || '海里没有瓶子了，或者出错了。')
        if (waitTime) {
          startCooldown('pickup', waitTime)
        }
      }
    } catch (error) {
      console.error('Pickup request failed', error)
      setPickupStatus('请求失败，请检查网络连接。')
      setCurrentBottle(null)
    } finally {
      setLoadingAction((prev) => ({ ...prev, pickup: false }))
    }
  }, [cooldowns.pickup, isPicking, startCooldown])

  const handleReaction = useCallback(
    async (reaction) => {
      if (!currentBottle) {
        return
      }
      setReactionDisabled(true)
      try {
        const response = await fetch(`${API_BASE_URL}/react`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ bottle_id: currentBottle.id, reaction }),
        })
        const data = await response.json()
        if (response.ok && data.success) {
          setCurrentBottle((prev) =>
            prev
              ? {
                  ...prev,
                  likes: reaction === 'like' ? formatCount(prev.likes) + 1 : prev.likes,
                  dislikes: reaction === 'dislike' ? formatCount(prev.dislikes) + 1 : prev.dislikes,
                }
              : prev,
          )
          setPickupStatus(
            reaction === 'like' ? '感谢您的点赞！' : '已记录您的反馈，该瓶子被捡起的概率将会降低。',
          )
        } else {
          setPickupStatus(data.error || '记录反馈时出错。')
          setReactionDisabled(false)
        }
      } catch (error) {
        console.error('Reaction request failed', error)
        setPickupStatus('请求失败，请稍后再试。')
        setReactionDisabled(false)
      }
    },
    [currentBottle],
  )

  const nameCharCount = useMemo(() => formData.name.length, [formData.name])
  const messageCharCount = useMemo(() => formData.message.length, [formData.message])

  return (
    <div className="page-wrapper">
      <div className="background-overlay" aria-hidden="true" />

      <div className="container">
        <h1>
          <i className="fas fa-heart heart-icon" /> 萌芽漂流瓶{' '}
          <i className="fas fa-heart heart-icon" />
        </h1>
        <p className="tagline">让心意随海浪飘向远方，邂逅那个懂你的人(´,,•ω•,,)♡...</p>


        <div className="stats-container">
          <p>
            <i className="fas fa-wine-bottle" /> 海洋中共有{' '}
            <span id="total-bottles">{formatCount(stats.total_bottles)}</span> 个漂流瓶在寻找有缘人
          </p>
        </div>

        <div className="action-section throw-section">
          <h2>
            <i className="fas fa-paper-plane" /> 扔一个漂流瓶(,,・ω・,,)
          </h2>
          <form id="throw-bottle-form" onSubmit={handleThrowSubmit}>
            <div>
              <label htmlFor="name">
                你的昵称:{' '}
                <span className={`char-count ${nameCharCount >= limits.name ? 'char-count-limit' : ''}`}>
                  <span id="name-char-count">{nameCharCount}</span>/{' '}
                  <span id="name-limit">{limits.name}</span>
                </span>
              </label>
              <input
                id="name"
                name="name"
                type="text"
                value={formData.name}
                onChange={handleInputChange}
                maxLength={limits.name}
                placeholder="告诉对方你是谁..."
                required
              />
            </div>

            <div>
              <label htmlFor="message">
                漂流瓶内容:{' '}
                <span
                  className={`char-count ${
                    messageCharCount >= limits.message ? 'char-count-limit' : ''
                  }`}
                >
                  <span id="message-char-count">{messageCharCount}</span>/{' '}
                  <span id="message-limit">{limits.message}</span>
                </span>
              </label>
              <textarea
                id="message"
                name="message"
                rows="4"
                value={formData.message}
                onChange={handleInputChange}
                maxLength={limits.message}
                placeholder="写下你想说的话，也许会有人懂..."
                required
              />
            </div>

            <div>
              <label htmlFor="gender">性别:</label>
              <select id="gender" name="gender" value={formData.gender} onChange={handleInputChange}>
                <option value="保密">保密</option>
                <option value="男">男</option>
                <option value="女">女</option>
              </select>
            </div>

            <div>
              <label htmlFor="qq">QQ号 (选填):</label>
              <input
                id="qq"
                name="qq"
                type="text"
                value={formData.qq}
                inputMode="numeric"
                pattern="[0-9]*"
                onChange={handleInputChange}
                placeholder="填写QQ号展示头像..."
              />
            </div>

            {cooldowns.throw > 0 ? (
              <div id="throw-cooldown" className="cooldown-timer">
                <i className="fas fa-hourglass-half" /> 冷却中: <span id="throw-countdown">{cooldowns.throw}</span> 秒
              </div>
            ) : (
              <button type="submit" id="throw-button" className="btn-throw" disabled={isThrowing}>
                <i className="fas fa-paper-plane" /> {isThrowing ? '正在扔瓶子...' : '扔出去'}
              </button>
            )}
          </form>
          <p id="throw-status">{throwStatus}</p>
        </div>

        <div className="action-section pickup-section">
          <h2>
            <i className="fas fa-search-location" /> 捡一个漂流瓶(,,・ω・,,)
          </h2>

          {cooldowns.pickup > 0 ? (
            <div id="pickup-cooldown" className="cooldown-timer">
              <i className="fas fa-hourglass-half" /> 冷却中: <span id="pickup-countdown">{cooldowns.pickup}</span> 秒
            </div>
          ) : (
            <button
              type="button"
              id="pickup-bottle-button"
              className="btn-pickup"
              onClick={handlePickup}
              disabled={isPicking}
            >
              <i className="fas fa-hand-paper" /> {isPicking ? '正在打捞...' : '捡瓶子'}
            </button>
          )}

          {currentBottle && (
            <div id="bottle-display" className="appear">
              <div className="bottle-header">
                {currentBottle.qq_avatar_url ? (
                  <img id="bottle-avatar" src={currentBottle.qq_avatar_url} alt="QQ Avatar" />
                ) : null}
                <h3>
                  来自 <span id="bottle-name">{currentBottle.name}</span>{' '}
                  <span className="gender-badge" id="bottle-gender">
                    {currentBottle.gender || '保密'}
                  </span>{' '}
                  的漂流瓶
                </h3>
              </div>

              <div className="message-content">
                <p id="bottle-message">{currentBottle.message}</p>
              </div>

              <div className="bottle-footer">
                <div className="bottle-info">
                  <small>
                    <i className="far fa-clock" /> 时间: <span id="bottle-timestamp">{currentBottle.timestamp}</span>
                  </small>
                  <small>
                    <i className="fas fa-map-marker-alt" /> IP:{' '}
                    <span id="bottle-ip">{currentBottle.ip_address || '未知'}</span>
                  </small>
                  {currentBottle.qq_number ? (
                    <small id="bottle-qq-number">
                      <i className="fab fa-qq" /> QQ: <span id="qq-number-val">{currentBottle.qq_number}</span>
                    </small>
                  ) : null}
                </div>

                <div className="bottle-reactions">
                  <button
                    type="button"
                    id="like-button"
                    className="reaction-btn like-btn"
                    onClick={() => handleReaction('like')}
                    disabled={reactionDisabled}
                  >
                    <i className="far fa-thumbs-up" /> <span id="like-count">{formatCount(currentBottle.likes)}</span>
                  </button>
                  <button
                    type="button"
                    id="dislike-button"
                    className="reaction-btn dislike-btn"
                    onClick={() => handleReaction('dislike')}
                    disabled={reactionDisabled}
                  >
                    <i className="far fa-thumbs-down" />{' '}
                    <span id="dislike-count">{formatCount(currentBottle.dislikes)}</span>
                  </button>
                </div>
              </div>
            </div>
          )}

          <p id="pickup-status">{pickupStatus}</p>
        </div>

        <footer>
          <p>
            © 2025 萌芽漂流瓶-蜀ICP备2025151694号 <i className="fas fa-heart" />
          </p>

        </footer>
      </div>
    </div>
  )
}

export default App
