/**
 * Cloudflare KV Demo Component
 * 
 * This component demonstrates how to use the Cloudflare KV utilities
 * in a React application with proper loading states and error handling.
 */

import React, { useState } from 'react'
import { useCloudflareKV, useKVValue } from '../hooks/useCloudflareKV'

interface DemoData {
  message: string
  timestamp: string
  counter: number
}

export const CloudflareKVDemo: React.FC = () => {
  const [inputKey, setInputKey] = useState('demo:test')
  const [inputValue, setInputValue] = useState('Hello, Cloudflare KV!')
  const [searchPrefix, setSearchPrefix] = useState('demo:')
  const [logs, setLogs] = useState<string[]>([])

  // Add log function
  const addLog = (message: string) => {
    const timestamp = new Date().toLocaleTimeString()
    const logMessage = `[${timestamp}] ${message}`
    console.log(logMessage)
    setLogs(prev => [logMessage, ...prev].slice(0, 20)) // Keep last 20 logs
  }

  // Use the general KV hook
  const kv = useCloudflareKV()

  // Use the specific value hook for a counter
  const {
    value: counterValue,
    loading: counterLoading,
    error: counterError,
    save: saveCounter,
    refresh: refreshCounter
  } = useKVValue<number>('demo:counter', true, true)

  // Log initial state
  React.useEffect(() => {
    addLog('CloudflareKVDemo component initialized')
    addLog(`KV loading state: ${kv.isLoading}`)
    addLog(`KV has error: ${kv.hasError}`)
    if (kv.hasError) {
      addLog(`KV errors: ${JSON.stringify(kv.errors)}`)
    }
  }, [kv.isLoading, kv.hasError, kv.errors])

  // Handle putting a value
  const handlePutValue = async () => {
    if (!inputKey || !inputValue) {
      addLog('❌ Put operation failed: Key or value is empty')
      alert('❌ Please enter both key and value')
      return
    }

    addLog(`🔄 Starting put operation for key: ${inputKey}`)

    try {
      const data: DemoData = {
        message: inputValue,
        timestamp: new Date().toISOString(),
        counter: (typeof counterValue === 'number' ? counterValue : 0) + 1
      }

      addLog(`📤 Sending data: ${JSON.stringify(data)}`)
      const result = await kv.put(inputKey, data)
      addLog(`✅ Put operation successful: ${JSON.stringify(result)}`)
      alert('✅ Value stored successfully!')
    } catch (error) {
      const errorMessage = (error as Error).message
      addLog(`❌ Put operation failed: ${errorMessage}`)
      alert('❌ Failed to store value: ' + errorMessage)
    }
  }

  // Handle getting a value
  const handleGetValue = async () => {
    if (!inputKey) {
      addLog('❌ Get operation failed: Key is empty')
      alert('❌ Please enter a key')
      return
    }

    addLog(`🔄 Starting get operation for key: ${inputKey}`)

    try {
      const result = await kv.get<DemoData>(inputKey)
      if (result) {
        addLog(`✅ Get operation successful: ${JSON.stringify(result)}`)
        alert(`✅ Retrieved value: ${JSON.stringify(result, null, 2)}`)
      } else {
        addLog(`ℹ️ Get operation completed: Key not found`)
        alert('ℹ️ Key not found')
      }
    } catch (error) {
      const errorMessage = (error as Error).message
      addLog(`❌ Get operation failed: ${errorMessage}`)
      alert('❌ Failed to get value: ' + errorMessage)
    }
  }

  // Handle deleting a value
  const handleDeleteValue = async () => {
    if (!inputKey) {
      addLog('❌ Delete operation failed: Key is empty')
      alert('❌ Please enter a key')
      return
    }

    addLog(`🔄 Starting delete operation for key: ${inputKey}`)

    try {
      const result = await kv.delete(inputKey)
      addLog(`✅ Delete operation successful: ${JSON.stringify(result)}`)
      alert('✅ Value deleted successfully!')
    } catch (error) {
      const errorMessage = (error as Error).message
      addLog(`❌ Delete operation failed: ${errorMessage}`)
      alert('❌ Failed to delete value: ' + errorMessage)
    }
  }

  // Handle listing keys
  const handleListKeys = async () => {
    addLog(`🔄 Starting list keys operation with prefix: ${searchPrefix}`)

    try {
      const result = await kv.listKeys(searchPrefix, 50)
      addLog(`✅ List keys operation successful: Found ${result.result.keys.length} keys`)
      const keyNames = result.result.keys.map(k => k.name).join('\n')
      alert(`✅ Found keys:\n${keyNames || 'No keys found'}`)
    } catch (error) {
      const errorMessage = (error as Error).message
      addLog(`❌ List keys operation failed: ${errorMessage}`)
      alert('❌ Failed to list keys: ' + errorMessage)
    }
  }

  // Handle incrementing counter
  const handleIncrementCounter = async () => {
    try {
      const newValue = (typeof counterValue === 'number' ? counterValue : 0) + 1
      await saveCounter(newValue)
    } catch (error) {
      alert('❌ Failed to increment counter: ' + (error as Error).message)
    }
  }

  // Handle batch operations
  const handleBatchPut = async () => {
    try {
      const entries = [
        { key: 'batch:item1', value: { name: 'Item 1', price: 10.99 } },
        { key: 'batch:item2', value: { name: 'Item 2', price: 15.50 } },
        { key: 'batch:item3', value: { name: 'Item 3', price: 8.75 } }
      ]

      await kv.putBatch(entries)
      alert('✅ Batch operation completed!')
    } catch (error) {
      alert('❌ Batch operation failed: ' + (error as Error).message)
    }
  }

  return (
    <div className="max-w-4xl mx-auto p-6 space-y-8">
      <div className="bg-white rounded-lg shadow-lg p-6">
        <h1 className="text-3xl font-bold text-gray-900 mb-6">
          Cloudflare KV Demo
        </h1>
        
        {/* Loading indicator */}
        {kv.isLoading && (
          <div className="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
            <div className="flex items-center">
              <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600 mr-2"></div>
              <span className="text-blue-800">Processing...</span>
            </div>
          </div>
        )}

        {/* Error display */}
        {kv.hasError && (
          <div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
            <h3 className="text-red-800 font-medium mb-2">Errors:</h3>
            <ul className="text-red-700 text-sm space-y-1">
              {kv.errors.get && <li>Get: {kv.errors.get}</li>}
              {kv.errors.put && <li>Put: {kv.errors.put}</li>}
              {kv.errors.delete && <li>Delete: {kv.errors.delete}</li>}
              {kv.errors.list && <li>List: {kv.errors.list}</li>}
            </ul>
          </div>
        )}

        {/* Counter Section */}
        <div className="bg-gray-50 rounded-lg p-4 mb-6">
          <h2 className="text-xl font-semibold text-gray-900 mb-4">
            Auto-loaded Counter
          </h2>
          <div className="flex items-center space-x-4">
            <div className="text-lg">
              Current value: 
              <span className="font-mono font-bold ml-2">
                {counterLoading ? '...' : counterValue || 0}
              </span>
            </div>
            <button
              onClick={handleIncrementCounter}
              disabled={counterLoading}
              className="bg-blue-500 hover:bg-blue-600 disabled:bg-gray-400 text-white px-4 py-2 rounded-lg transition-colors"
            >
              Increment
            </button>
            <button
              onClick={refreshCounter}
              disabled={counterLoading}
              className="bg-gray-500 hover:bg-gray-600 disabled:bg-gray-400 text-white px-4 py-2 rounded-lg transition-colors"
            >
              Refresh
            </button>
          </div>
          {counterError && (
            <p className="text-red-600 text-sm mt-2">{counterError}</p>
          )}
        </div>

        {/* Manual Operations Section */}
        <div className="space-y-6">
          <h2 className="text-xl font-semibold text-gray-900">
            Manual Operations
          </h2>

          {/* Key-Value Input */}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-2">
                Key
              </label>
              <input
                type="text"
                value={inputKey}
                onChange={(e) => setInputKey(e.target.value)}
                className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                placeholder="Enter key name"
              />
            </div>
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-2">
                Value
              </label>
              <input
                type="text"
                value={inputValue}
                onChange={(e) => setInputValue(e.target.value)}
                className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                placeholder="Enter value"
              />
            </div>
          </div>

          {/* Action Buttons */}
          <div className="flex flex-wrap gap-3">
            <button
              onClick={handlePutValue}
              disabled={kv.isLoading || !inputKey || !inputValue}
              className="bg-green-500 hover:bg-green-600 disabled:bg-gray-400 text-white px-4 py-2 rounded-lg transition-colors"
            >
              Put Value
            </button>
            <button
              onClick={handleGetValue}
              disabled={kv.isLoading || !inputKey}
              className="bg-blue-500 hover:bg-blue-600 disabled:bg-gray-400 text-white px-4 py-2 rounded-lg transition-colors"
            >
              Get Value
            </button>
            <button
              onClick={handleDeleteValue}
              disabled={kv.isLoading || !inputKey}
              className="bg-red-500 hover:bg-red-600 disabled:bg-gray-400 text-white px-4 py-2 rounded-lg transition-colors"
            >
              Delete Value
            </button>
          </div>

          {/* List Keys Section */}
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-2">
              Search Prefix
            </label>
            <div className="flex gap-3">
              <input
                type="text"
                value={searchPrefix}
                onChange={(e) => setSearchPrefix(e.target.value)}
                className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                placeholder="Enter prefix to search"
              />
              <button
                onClick={handleListKeys}
                disabled={kv.isLoading}
                className="bg-purple-500 hover:bg-purple-600 disabled:bg-gray-400 text-white px-4 py-2 rounded-lg transition-colors"
              >
                List Keys
              </button>
            </div>
          </div>

          {/* Batch Operations */}
          <div>
            <button
              onClick={handleBatchPut}
              disabled={kv.isLoading}
              className="bg-orange-500 hover:bg-orange-600 disabled:bg-gray-400 text-white px-4 py-2 rounded-lg transition-colors"
            >
              Batch Put Demo Items
            </button>
          </div>

          {/* Clear States */}
          <div>
            <button
              onClick={kv.clearStates}
              className="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors"
            >
              Clear All States
            </button>
            <button
              onClick={() => setLogs([])}
              className="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors ml-3"
            >
              Clear Logs
            </button>
          </div>
        </div>
      </div>

      {/* Debug Logs Section */}
      <div className="bg-white rounded-lg shadow-lg p-6 mt-6">
        <h2 className="text-xl font-semibold text-gray-900 mb-4">
          Debug Logs
        </h2>
        <div className="bg-gray-900 text-green-400 p-4 rounded-lg font-mono text-sm max-h-96 overflow-y-auto">
          {logs.length === 0 ? (
            <div className="text-gray-500">No logs yet...</div>
          ) : (
            logs.map((log, index) => (
              <div key={index} className="mb-1">
                {log}
              </div>
            ))
          )}
        </div>
      </div>
    </div>
  )
}

export default CloudflareKVDemo
