import React, { useState, useEffect } from 'react'
import { useAuth } from './auth/AuthContext'
import LoadingError from './LoadingError'
import Toast from './Toast'
import './Integrations.css'

function FitbitIntegration({ onNavigate }) {
  const { authFetch } = useAuth()
  const [connected, setConnected] = useState(false)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [message, setMessage] = useState('')
  const [oauthError, setOauthError] = useState('')
  const [toastMessage, setToastMessage] = useState(null)
  const [isLoadingError, setIsLoadingError] = useState(false)
  const [syncing, setSyncing] = useState(false)

  const [stats, setStats] = useState({
    steps: { value: 0, goal: 10000 },
    floors: { value: 0, goal: 10 }
  })

  const [bindings, setBindings] = useState({
    steps_task_id: null,
    floors_task_id: null,
    steps_goal_task_id: null,
    steps_goal_subtask_id: null,
    floors_goal_task_id: null,
    floors_goal_subtask_id: null
  })
  const [editedBindings, setEditedBindings] = useState(bindings)
  const [savingStepsBindings, setSavingStepsBindings] = useState(false)
  const [savingFloorsBindings, setSavingFloorsBindings] = useState(false)

  const [tasks, setTasks] = useState([])
  const [loadingTasks, setLoadingTasks] = useState(false)
  const [stepsGoalSubtasks, setStepsGoalSubtasks] = useState([])
  const [floorsGoalSubtasks, setFloorsGoalSubtasks] = useState([])

  const oauthStatusRef = React.useRef(null)

  useEffect(() => {
    const params = new URLSearchParams(window.location.search)
    const integration = params.get('integration')
    const status = params.get('status')
    if (integration === 'fitbit') {
      oauthStatusRef.current = status
      if (status === 'connected') {
        setMessage('Fitbit успешно подключен!')
      } else if (status === 'error') {
        const errorMsg = params.get('message') || 'unknown_error'
        const errorMessages = {
          'config_error': 'Ошибка конфигурации сервера. Обратитесь к администратору.',
          'invalid_state': 'Недействительный токен авторизации. Попробуйте ещё раз.',
          'no_code': 'Не получен код авторизации от Fitbit. Попробуйте ещё раз.',
          'token_exchange_failed': 'Не удалось обменять код на токен. Проверьте настройки Fitbit приложения.',
          'user_info_failed': 'Не удалось получить информацию о пользователе Fitbit.',
          'db_error': 'Ошибка сохранения данных. Попробуйте ещё раз.',
          'unknown_error': 'Произошла неизвестная ошибка при подключении Fitbit.'
        }
        setOauthError(errorMessages[errorMsg] || `Ошибка: ${errorMsg}`)
      }
      window.history.replaceState({}, '', window.location.pathname)
    }
    checkStatus()
  }, [])

  useEffect(() => {
    if (connected) {
      loadStats()
      loadTasks()
    }
  }, [connected])

  useEffect(() => {
    if (!editedBindings.steps_goal_task_id) {
      setStepsGoalSubtasks([])
      return
    }
    let cancelled = false
    authFetch(`/api/tasks/${editedBindings.steps_goal_task_id}`)
      .then((r) => r.ok ? r.json() : null)
      .then((data) => {
        if (!cancelled && data?.subtasks) {
          setStepsGoalSubtasks(data.subtasks.map((s) => ({ id: s.task.id, name: s.task.name })))
        } else if (!cancelled) {
          setStepsGoalSubtasks([])
        }
      })
      .catch(() => {
        if (!cancelled) setStepsGoalSubtasks([])
      })
    return () => { cancelled = true }
  }, [editedBindings.steps_goal_task_id, authFetch])

  useEffect(() => {
    if (!editedBindings.floors_goal_task_id) {
      setFloorsGoalSubtasks([])
      return
    }
    let cancelled = false
    authFetch(`/api/tasks/${editedBindings.floors_goal_task_id}`)
      .then((r) => r.ok ? r.json() : null)
      .then((data) => {
        if (!cancelled && data?.subtasks) {
          setFloorsGoalSubtasks(data.subtasks.map((s) => ({ id: s.task.id, name: s.task.name })))
        } else if (!cancelled) {
          setFloorsGoalSubtasks([])
        }
      })
      .catch(() => {
        if (!cancelled) setFloorsGoalSubtasks([])
      })
    return () => { cancelled = true }
  }, [editedBindings.floors_goal_task_id, authFetch])

  const checkStatus = async () => {
    try {
      setLoading(true)
      setError('')
      const response = await authFetch('/api/integrations/fitbit/status')
      if (!response.ok) {
        throw new Error('Ошибка при проверке статуса')
      }
      const data = await response.json()
      setConnected(data.connected || false)
      if (data.connected && data.bindings) {
        const b = data.bindings
        const normalized = {
          steps_task_id: b.steps_task_id ?? null,
          floors_task_id: b.floors_task_id ?? null,
          steps_goal_task_id: b.steps_goal_task_id ?? null,
          steps_goal_subtask_id: b.steps_goal_subtask_id ?? null,
          floors_goal_task_id: b.floors_goal_task_id ?? null,
          floors_goal_subtask_id: b.floors_goal_subtask_id ?? null
        }
        setBindings(normalized)
        setEditedBindings(normalized)
      }
      if (oauthStatusRef.current === 'connected' && !data.connected) {
        setOauthError('Авторизация в Fitbit прошла, но подключение не сохранилось. Попробуйте ещё раз.')
        setMessage('')
      }
      oauthStatusRef.current = null
    } catch (error) {
      console.error('Error checking status:', error)
      setError(error.message || 'Не удалось проверить статус')
      setIsLoadingError(true)
    } finally {
      setLoading(false)
    }
  }

  const loadStats = async () => {
    try {
      const response = await authFetch('/api/integrations/fitbit/stats')
      if (!response.ok) {
        throw new Error('Ошибка при загрузке статистики')
      }
      const data = await response.json()
      setStats({
        steps: {
          value: data.steps?.value ?? 0,
          goal: data.steps?.goal ?? 10000
        },
        floors: {
          value: data.floors?.value ?? 0,
          goal: data.floors?.goal ?? 10
        }
      })
    } catch (error) {
      console.error('Error loading stats:', error)
    }
  }

  const loadTasks = async (silent = false) => {
    try {
      if (!silent) setLoadingTasks(true)
      const response = await authFetch('/api/tasks')
      if (!response.ok) {
        throw new Error('Ошибка при загрузке задач')
      }
      const data = await response.json()
      setTasks(data || [])
    } catch (error) {
      if (!silent) console.error('Error loading tasks:', error)
    } finally {
      if (!silent) setLoadingTasks(false)
    }
  }

  const handleConnect = async () => {
    try {
      setLoading(true)
      setError('')
      const response = await authFetch('/api/integrations/fitbit/oauth/connect')
      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}))
        throw new Error(errorData.error || 'Ошибка при подключении Fitbit')
      }
      const data = await response.json()
      if (data.auth_url) {
        window.location.href = data.auth_url
      } else {
        throw new Error('URL для авторизации не получен')
      }
    } catch (error) {
      console.error('Error connecting Fitbit:', error)
      setToastMessage({ text: error.message || 'Не удалось подключить Fitbit', type: 'error' })
      setLoading(false)
    }
  }

  const handleDisconnect = async () => {
    if (!window.confirm('Вы уверены, что хотите отключить Fitbit?')) {
      return
    }
    try {
      setLoading(true)
      setError('')
      const response = await authFetch('/api/integrations/fitbit/disconnect', {
        method: 'DELETE',
      })
      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}))
        throw new Error(errorData.error || 'Ошибка при отключении')
      }
      setConnected(false)
      setStats({
        steps: { value: 0, goal: 10000 },
        floors: { value: 0, goal: 10 }
      })
      setToastMessage({ text: 'Fitbit отключен', type: 'success' })
    } catch (error) {
      console.error('Error disconnecting:', error)
      setToastMessage({ text: error.message || 'Не удалось отключить Fitbit', type: 'error' })
    } finally {
      setLoading(false)
    }
  }

  const handleSync = async () => {
    try {
      setSyncing(true)
      const response = await authFetch('/api/integrations/fitbit/sync', {
        method: 'POST',
      })
      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}))
        throw new Error(errorData.error || 'Ошибка при синхронизации')
      }
      setToastMessage({ text: 'Данные синхронизированы', type: 'success' })
      await loadStats()
    } catch (error) {
      console.error('Error syncing:', error)
      setToastMessage({ text: error.message || 'Не удалось синхронизировать данные', type: 'error' })
    } finally {
      setSyncing(false)
    }
  }

  const handleSaveStepsBindings = async () => {
    try {
      setSavingStepsBindings(true)
      const response = await authFetch('/api/integrations/fitbit/bindings/steps', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          steps_task_id: editedBindings.steps_task_id,
          steps_goal_task_id: editedBindings.steps_goal_task_id,
          steps_goal_subtask_id: editedBindings.steps_goal_subtask_id
        })
      })
      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}))
        throw new Error(errorData.error || 'Ошибка при сохранении привязок')
      }
      setBindings(prev => ({
        ...prev,
        steps_task_id: editedBindings.steps_task_id,
        steps_goal_task_id: editedBindings.steps_goal_task_id,
        steps_goal_subtask_id: editedBindings.steps_goal_subtask_id
      }))
      setToastMessage({ text: 'Привязки шагов сохранены', type: 'success' })
    } catch (error) {
      console.error('Error saving steps bindings:', error)
      setToastMessage({ text: error.message || 'Не удалось сохранить привязки', type: 'error' })
    } finally {
      setSavingStepsBindings(false)
    }
  }

  const handleSaveFloorsBindings = async () => {
    try {
      setSavingFloorsBindings(true)
      const response = await authFetch('/api/integrations/fitbit/bindings/floors', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          floors_task_id: editedBindings.floors_task_id,
          floors_goal_task_id: editedBindings.floors_goal_task_id,
          floors_goal_subtask_id: editedBindings.floors_goal_subtask_id
        })
      })
      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}))
        throw new Error(errorData.error || 'Ошибка при сохранении привязок')
      }
      setBindings(prev => ({
        ...prev,
        floors_task_id: editedBindings.floors_task_id,
        floors_goal_task_id: editedBindings.floors_goal_task_id,
        floors_goal_subtask_id: editedBindings.floors_goal_subtask_id
      }))
      setToastMessage({ text: 'Привязки этажей сохранены', type: 'success' })
    } catch (error) {
      console.error('Error saving floors bindings:', error)
      setToastMessage({ text: error.message || 'Не удалось сохранить привязки', type: 'error' })
    } finally {
      setSavingFloorsBindings(false)
    }
  }

  const getProgressTasks = () => {
    return tasks.filter(t => t.has_progression || t.progression_base != null)
  }

  const getParentTasks = () => {
    return tasks.filter(t => (t.subtasks_count ?? 0) > 0)
  }

  const getProgressPercent = (value, goal) => {
    if (!goal || goal === 0) return 0
    return Math.min(100, (value / goal) * 100)
  }

  const getProgressColor = (value, goal) => {
    if (value >= goal) return 'text-green-600'
    if (value >= goal * 0.5) return 'text-blue-600'
    return 'text-gray-600'
  }

  const isStepsBindingsDirty =
    (editedBindings.steps_task_id ?? null) !== (bindings.steps_task_id ?? null) ||
    (editedBindings.steps_goal_task_id ?? null) !== (bindings.steps_goal_task_id ?? null) ||
    (editedBindings.steps_goal_subtask_id ?? null) !== (bindings.steps_goal_subtask_id ?? null)

  const isFloorsBindingsDirty =
    (editedBindings.floors_task_id ?? null) !== (bindings.floors_task_id ?? null) ||
    (editedBindings.floors_goal_task_id ?? null) !== (bindings.floors_goal_task_id ?? null) ||
    (editedBindings.floors_goal_subtask_id ?? null) !== (bindings.floors_goal_subtask_id ?? null)

  const handleClose = () => {
    setEditedBindings(bindings)
    onNavigate?.('profile')
  }

  if (isLoadingError && !loading) {
    return (
      <div className="p-4 md:p-6">
        <button className="close-x-button" onClick={handleClose} title="Закрыть">
          ✕
        </button>
        <LoadingError onRetry={checkStatus} />
      </div>
    )
  }

  return (
    <div className="p-4 md:p-6">
      <button className="close-x-button" onClick={handleClose} title="Закрыть">
        ✕
      </button>

      <h1 className="text-2xl font-bold mb-6">Fitbit</h1>

      {message && (
        <div className="bg-green-50 border border-green-200 rounded-lg p-4 mb-6">
          <p className="text-green-800">{message}</p>
          <button onClick={() => setMessage('')} className="text-green-600 text-sm underline mt-2">Скрыть</button>
        </div>
      )}

      {loading ? (
        <div className="flex justify-center items-center h-32">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-600"></div>
        </div>
      ) : connected ? (
        <div>
          {/* Группа: Шаги */}
          <div className="bg-white rounded-lg shadow-md p-6 mb-6">
            <h2 className="text-lg font-semibold mb-4">Шаги</h2>

            <div className="space-y-4">
              <div>
                <div className="flex justify-between items-center mb-2">
                  <span className="text-gray-600 text-sm">Сегодня</span>
                  <span className={`font-bold ${getProgressColor(stats.steps.value, stats.steps.goal)}`}>
                    {stats.steps.value.toLocaleString()} / {stats.steps.goal.toLocaleString()}
                  </span>
                </div>
                <div className="w-full bg-gray-200 rounded-full h-3">
                  <div
                    className="bg-indigo-600 h-3 rounded-full transition-all"
                    style={{ width: `${getProgressPercent(stats.steps.value, stats.steps.goal)}%` }}
                  ></div>
                </div>
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">Прогресс шагов</label>
                <p className="text-xs text-gray-500 mb-1">Задача</p>
                <select
                  value={editedBindings.steps_task_id ?? ''}
                  onChange={(e) => setEditedBindings({
                    ...editedBindings,
                    steps_task_id: e.target.value ? parseInt(e.target.value, 10) : null
                  })}
                  onFocus={() => loadTasks(true)}
                  disabled={loadingTasks}
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg disabled:bg-gray-100"
                >
                  <option value="">{loadingTasks ? 'Загрузка...' : 'Не выбрано'}</option>
                  {!loadingTasks && getProgressTasks().map(task => (
                    <option key={task.id} value={task.id}>{task.name}</option>
                  ))}
                </select>
              </div>

              <div>
                <h3 className="text-sm font-medium text-gray-700 mb-2">Достижение цели</h3>
                <div className="pl-0 space-y-2">
                  <div>
                    <label className="block text-sm text-gray-600 mb-1">Задача</label>
                    <select
                      value={editedBindings.steps_goal_task_id ?? ''}
                      onChange={(e) => setEditedBindings({
                        ...editedBindings,
                        steps_goal_task_id: e.target.value ? parseInt(e.target.value, 10) : null,
                        steps_goal_subtask_id: null
                      })}
                      onFocus={() => loadTasks(true)}
                      disabled={loadingTasks}
                      className="w-full px-3 py-2 border border-gray-300 rounded-lg disabled:bg-gray-100"
                    >
                      <option value="">{loadingTasks ? 'Загрузка...' : 'Не выбрано'}</option>
                      {!loadingTasks && tasks.map(task => (
                        <option key={task.id} value={task.id}>{task.name}</option>
                      ))}
                    </select>
                  </div>
                  {editedBindings.steps_goal_task_id && stepsGoalSubtasks.length > 0 && (
                    <div>
                      <label className="block text-sm text-gray-600 mb-1">Подзадача</label>
                      <select
                        value={editedBindings.steps_goal_subtask_id ?? ''}
                        onChange={(e) => setEditedBindings({
                          ...editedBindings,
                          steps_goal_subtask_id: e.target.value ? parseInt(e.target.value, 10) : null
                        })}
                        disabled={loadingTasks}
                        className="w-full px-3 py-2 border border-gray-300 rounded-lg disabled:bg-gray-100"
                      >
                        <option value="">Не выбрано</option>
                        {stepsGoalSubtasks.map(subtask => (
                          <option key={subtask.id} value={subtask.id}>{subtask.name}</option>
                        ))}
                      </select>
                    </div>
                  )}
                </div>
              </div>

              {isStepsBindingsDirty && (
                <button
                  onClick={handleSaveStepsBindings}
                  disabled={savingStepsBindings}
                  className="mt-3 px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors disabled:opacity-50"
                >
                  {savingStepsBindings ? 'Сохранение...' : 'Сохранить'}
                </button>
              )}
            </div>
          </div>

          {/* Группа: Этажи */}
          <div className="bg-white rounded-lg shadow-md p-6 mb-6">
            <h2 className="text-lg font-semibold mb-4">Этажи</h2>

            <div className="space-y-4">
              <div>
                <div className="flex justify-between items-center mb-2">
                  <span className="text-gray-600 text-sm">Сегодня</span>
                  <span className={`font-bold ${getProgressColor(stats.floors.value, stats.floors.goal)}`}>
                    {stats.floors.value} / {stats.floors.goal}
                  </span>
                </div>
                <div className="w-full bg-gray-200 rounded-full h-3">
                  <div
                    className="bg-indigo-600 h-3 rounded-full transition-all"
                    style={{ width: `${getProgressPercent(stats.floors.value, stats.floors.goal)}%` }}
                  ></div>
                </div>
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-700 mb-1">Прогресс этажей</label>
                <p className="text-xs text-gray-500 mb-1">Задача</p>
                <select
                  value={editedBindings.floors_task_id ?? ''}
                  onChange={(e) => setEditedBindings({
                    ...editedBindings,
                    floors_task_id: e.target.value ? parseInt(e.target.value, 10) : null
                  })}
                  onFocus={() => loadTasks(true)}
                  disabled={loadingTasks}
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg disabled:bg-gray-100"
                >
                  <option value="">{loadingTasks ? 'Загрузка...' : 'Не выбрано'}</option>
                  {!loadingTasks && getProgressTasks().map(task => (
                    <option key={task.id} value={task.id}>{task.name}</option>
                  ))}
                </select>
              </div>

              <div>
                <h3 className="text-sm font-medium text-gray-700 mb-2">Достижение цели</h3>
                <div className="pl-0 space-y-2">
                  <div>
                    <label className="block text-sm text-gray-600 mb-1">Задача</label>
                    <select
                      value={editedBindings.floors_goal_task_id ?? ''}
                      onChange={(e) => setEditedBindings({
                        ...editedBindings,
                        floors_goal_task_id: e.target.value ? parseInt(e.target.value, 10) : null,
                        floors_goal_subtask_id: null
                      })}
                      onFocus={() => loadTasks(true)}
                      disabled={loadingTasks}
                      className="w-full px-3 py-2 border border-gray-300 rounded-lg disabled:bg-gray-100"
                    >
                      <option value="">{loadingTasks ? 'Загрузка...' : 'Не выбрано'}</option>
                      {!loadingTasks && tasks.map(task => (
                        <option key={task.id} value={task.id}>{task.name}</option>
                      ))}
                    </select>
                  </div>
                  {editedBindings.floors_goal_task_id && floorsGoalSubtasks.length > 0 && (
                    <div>
                      <label className="block text-sm text-gray-600 mb-1">Подзадача</label>
                      <select
                        value={editedBindings.floors_goal_subtask_id ?? ''}
                        onChange={(e) => setEditedBindings({
                          ...editedBindings,
                          floors_goal_subtask_id: e.target.value ? parseInt(e.target.value, 10) : null
                        })}
                        disabled={loadingTasks}
                        className="w-full px-3 py-2 border border-gray-300 rounded-lg disabled:bg-gray-100"
                      >
                        <option value="">Не выбрано</option>
                        {floorsGoalSubtasks.map(subtask => (
                          <option key={subtask.id} value={subtask.id}>{subtask.name}</option>
                        ))}
                      </select>
                    </div>
                  )}
                </div>
              </div>

              {isFloorsBindingsDirty && (
                <button
                  onClick={handleSaveFloorsBindings}
                  disabled={savingFloorsBindings}
                  className="mt-3 px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors disabled:opacity-50"
                >
                  {savingFloorsBindings ? 'Сохранение...' : 'Сохранить'}
                </button>
              )}
            </div>
          </div>

          <button
            onClick={handleSync}
            disabled={syncing}
            className="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors disabled:opacity-50 mb-6"
          >
            {syncing ? 'Синхронизация...' : 'Синхронизировать'}
          </button>

          <div className="bg-blue-50 border border-blue-200 rounded-lg p-6 mb-6">
            <h3 className="text-lg font-semibold mb-3 text-blue-900">Как это работает</h3>
            <ul className="text-gray-700 space-y-2 text-sm">
              <li>• Данные синхронизируются автоматически каждые 4 часа</li>
              <li>• При синхронизации данные записываются в привязанные задачи</li>
              <li>• Задачи автоматически выполняются в конце дня (23:55)</li>
            </ul>
          </div>

          <button
            onClick={handleDisconnect}
            className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
          >
            Отключить Fitbit
          </button>
        </div>
      ) : (
        <div>
          {oauthError && (
            <div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
              <p className="text-red-800 font-medium">Ошибка подключения Fitbit</p>
              <p className="text-red-700 mt-1">{oauthError}</p>
              <button onClick={() => setOauthError('')} className="text-red-600 text-sm underline mt-2">Скрыть</button>
            </div>
          )}
          <div className="bg-white rounded-lg shadow-md p-6 mb-6">
            <h2 className="text-lg font-semibold mb-4">Подключение Fitbit</h2>
            <p className="text-gray-700 mb-4">
              Подключите свой Fitbit аккаунт для автоматической синхронизации шагов и этажей с вашими задачами.
            </p>
            <button
              onClick={handleConnect}
              className="px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors font-semibold"
            >
              Подключить Fitbit
            </button>
          </div>

          <div className="bg-blue-50 border border-blue-200 rounded-lg p-6">
            <h3 className="text-lg font-semibold mb-3 text-blue-900">Что нужно сделать</h3>
            <ol className="list-decimal list-inside space-y-2 text-gray-700">
              <li>Нажмите кнопку "Подключить Fitbit"</li>
              <li>Авторизуйтесь в Fitbit</li>
              <li>Разрешите доступ к данным о физической активности</li>
              <li>Настройте привязки к задачам</li>
            </ol>
          </div>
        </div>
      )}

      {toastMessage && (
        <Toast
          message={toastMessage.text}
          type={toastMessage.type}
          onClose={() => setToastMessage(null)}
        />
      )}
    </div>
  )
}

export default FitbitIntegration
