./kaisetsu-app/src/components/UserDictionaryModal.tsx

'use client';

import { useState, useEffect } from 'react';
import {
  X,
  BookOpen,
  Plus,
  Trash2,
  Search,
  Edit3,
  Check,
  Volume2,
  Loader2
} from 'lucide-react';

export interface DictionaryEntry {
  id: string;
  word: string;
  reading: string;
}

interface UserDictionaryModalProps {
  isOpen: boolean;
  onClose: () => void;
  entries: DictionaryEntry[];
  onEntriesChange: (entries: DictionaryEntry[]) => void;
}

export default function UserDictionaryModal({
  isOpen,
  onClose,
  entries,
  onEntriesChange
}: UserDictionaryModalProps) {
  const [searchQuery, setSearchQuery] = useState('');
  const [newWord, setNewWord] = useState('');
  const [newReading, setNewReading] = useState('');
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editWord, setEditWord] = useState('');
  const [editReading, setEditReading] = useState('');
  const [playingId, setPlayingId] = useState<string | null>(null);
  const [isLoadingAudio, setIsLoadingAudio] = useState(false);

  const filteredEntries = entries.filter(
    (entry) =>
      entry.word.toLowerCase().includes(searchQuery.toLowerCase()) ||
      entry.reading.toLowerCase().includes(searchQuery.toLowerCase())
  );

  const handleAdd = () => {
    if (newWord && newReading) {
      const newEntry: DictionaryEntry = {
        id: Date.now().toString(),
        word: newWord,
        reading: newReading
      };
      onEntriesChange([...entries, newEntry]);
      setNewWord('');
      setNewReading('');
    }
  };

  const handleDelete = (id: string) => {
    onEntriesChange(entries.filter((entry) => entry.id !== id));
  };

  const handleEdit = (entry: DictionaryEntry) => {
    setEditingId(entry.id);
    setEditWord(entry.word);
    setEditReading(entry.reading);
  };

  const handleSaveEdit = () => {
    if (editingId) {
      onEntriesChange(
        entries.map((entry) =>
          entry.id === editingId
            ? { ...entry, word: editWord, reading: editReading }
            : entry
        )
      );
      setEditingId(null);
      setEditWord('');
      setEditReading('');
    }
  };

  const handleCancelEdit = () => {
    setEditingId(null);
    setEditWord('');
    setEditReading('');
  };

  const handlePlayPreview = async (entry: DictionaryEntry) => {
    if (playingId === entry.id) return;

    setPlayingId(entry.id);
    setIsLoadingAudio(true);

    try {
      const response = await fetch('/api/tts', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          text: entry.reading,
          voiceType: '7nO7lVCISGqz9Dhm3AAx',
        }),
      });

      if (response.ok) {
        const audioBlob = await response.blob();
        const audioUrl = URL.createObjectURL(audioBlob);
        const audio = new Audio(audioUrl);

        audio.onended = () => {
          setPlayingId(null);
          URL.revokeObjectURL(audioUrl);
        };

        audio.onerror = () => {
          setPlayingId(null);
          URL.revokeObjectURL(audioUrl);
        };

        await audio.play();
      } else {
        setPlayingId(null);
      }
    } catch (error) {
      console.error('Preview error:', error);
      setPlayingId(null);
    } finally {
      setIsLoadingAudio(false);
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-black/40"
        onClick={onClose}
      />

      {/* Modal */}
      <div className="relative bg-white rounded-2xl shadow-2xl w-full max-w-2xl max-h-[80vh] overflow-hidden">
        {/* Header */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200">
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 rounded-lg bg-gray-900 flex items-center justify-center">
              <BookOpen className="w-5 h-5 text-white" />
            </div>
            <div>
              <h2 className="text-lg font-bold text-gray-900">
                ユーザー辞書
              </h2>
              <p className="text-xs text-gray-500">
                読み方をカスタマイズ(単語→読み方に置換)
              </p>
            </div>
          </div>
          <button
            onClick={onClose}
            className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
          >
            <X className="w-5 h-5 text-gray-500" />
          </button>
        </div>

        {/* Search */}
        <div className="px-6 py-4 border-b border-gray-200">
          <div className="relative">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
            <input
              type="text"
              placeholder="単語を検索..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="w-full pl-10 pr-4 py-2.5 bg-gray-50 border border-gray-200 focus:border-gray-400 rounded-xl text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-200"
            />
          </div>
        </div>

        {/* Add new entry */}
        <div className="px-6 py-4 bg-gray-50 border-b border-gray-200">
          <div className="flex items-end gap-3">
            <div className="flex-1">
              <label className="block text-xs font-medium text-gray-600 mb-1.5">
                単語(置換前)
              </label>
              <input
                type="text"
                placeholder="例: NVIDIA"
                value={newWord}
                onChange={(e) => setNewWord(e.target.value)}
                className="w-full px-3 py-2 bg-white border border-gray-200 rounded-lg text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-300"
              />
            </div>
            <div className="flex-1">
              <label className="block text-xs font-medium text-gray-600 mb-1.5">
                読み方(置換後)
              </label>
              <input
                type="text"
                placeholder="例: エヌビディア"
                value={newReading}
                onChange={(e) => setNewReading(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && handleAdd()}
                className="w-full px-3 py-2 bg-white border border-gray-200 rounded-lg text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-300"
              />
            </div>
            <button
              onClick={handleAdd}
              disabled={!newWord || !newReading}
              className="flex items-center gap-2 px-4 py-2 bg-gray-900 hover:bg-gray-800 disabled:bg-gray-300 disabled:cursor-not-allowed text-white rounded-lg transition-colors"
            >
              <Plus className="w-4 h-4" />
              追加
            </button>
          </div>
          <p className="text-xs text-gray-500 mt-2">
            Tip: TTSに送る前にテキスト内の「単語」が「読み方」に置換されます
          </p>
        </div>

        {/* Entry list */}
        <div className="overflow-y-auto max-h-[300px]">
          {filteredEntries.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-12 text-gray-400">
              <BookOpen className="w-12 h-12 mb-3 opacity-50" />
              <p className="text-sm">辞書に登録された単語がありません</p>
            </div>
          ) : (
            <div className="divide-y divide-gray-100">
              {filteredEntries.map((entry) => (
                <div
                  key={entry.id}
                  className="flex items-center justify-between px-6 py-3 hover:bg-gray-50 transition-colors"
                >
                  {editingId === entry.id ? (
                    <div className="flex-1 flex items-center gap-3">
                      <input
                        type="text"
                        value={editWord}
                        onChange={(e) => setEditWord(e.target.value)}
                        className="flex-1 px-3 py-1.5 bg-white border border-gray-400 rounded-lg text-gray-900 focus:outline-none"
                      />
                      <input
                        type="text"
                        value={editReading}
                        onChange={(e) => setEditReading(e.target.value)}
                        className="flex-1 px-3 py-1.5 bg-white border border-gray-400 rounded-lg text-gray-900 focus:outline-none"
                      />
                      <button
                        onClick={handleSaveEdit}
                        className="p-1.5 bg-gray-900 text-white rounded-lg hover:bg-gray-800 transition-colors"
                      >
                        <Check className="w-4 h-4" />
                      </button>
                      <button
                        onClick={handleCancelEdit}
                        className="p-1.5 bg-gray-100 text-gray-600 rounded-lg hover:bg-gray-200 transition-colors"
                      >
                        <X className="w-4 h-4" />
                      </button>
                    </div>
                  ) : (
                    <>
                      <div className="flex-1">
                        <div className="flex items-center gap-3">
                          <span className="font-medium text-gray-900">
                            {entry.word}
                          </span>
                          <span className="text-gray-400">→</span>
                          <span className="text-gray-700 font-medium">
                            {entry.reading}
                          </span>
                        </div>
                      </div>
                      <div className="flex items-center gap-1">
                        <button
                          onClick={() => handlePlayPreview(entry)}
                          disabled={playingId === entry.id}
                          className="p-1.5 text-gray-400 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors disabled:opacity-50"
                          title="試聴"
                        >
                          {playingId === entry.id ? (
                            <Loader2 className="w-4 h-4 animate-spin" />
                          ) : (
                            <Volume2 className="w-4 h-4" />
                          )}
                        </button>
                        <button
                          onClick={() => handleEdit(entry)}
                          className="p-1.5 text-gray-400 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors"
                          title="編集"
                        >
                          <Edit3 className="w-4 h-4" />
                        </button>
                        <button
                          onClick={() => handleDelete(entry.id)}
                          className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 rounded-lg transition-colors"
                          title="削除"
                        >
                          <Trash2 className="w-4 h-4" />
                        </button>
                      </div>
                    </>
                  )}
                </div>
              ))}
            </div>
          )}
        </div>

        {/* Footer */}
        <div className="flex items-center justify-between px-6 py-4 border-t border-gray-200 bg-gray-50">
          <p className="text-sm text-gray-500">
            {entries.length} 件の単語が登録されています
          </p>
          <button
            onClick={onClose}
            className="px-4 py-2 bg-gray-200 hover:bg-gray-300 text-gray-700 rounded-lg transition-colors"
          >
            閉じる
          </button>
        </div>
      </div>
    </div>
  );
}