// src/features/shopping/ShoppingList.tsx
import React, { useState, useMemo, useCallback } from 'react';
import type { ShoppingList, ShoppingListItem, User } from '../../types';
import { UserIcon } from '../../components/icons/UserIcon';
import { ListBulletIcon } from '../../components/icons/ListBulletIcon';
import { LoadingSpinner } from '../../components/LoadingSpinner';
import { TrashIcon } from '../../components/icons/TrashIcon';
import { SpeakerWaveIcon } from '../../components/icons/SpeakerWaveIcon';
import { generateSpeechFromText } from '../../services/aiApiClient';
import { decode, decodeAudioData } from '../../utils/audioUtils';
import { logger } from '../../services/logger.client';

interface ShoppingListComponentProps {
    user: User | null;
    lists: ShoppingList[];
    activeListId: number | null;
    onSelectList: (listId: number) => void;
    onCreateList: (name: string) => Promise<void>;
    onDeleteList: (listId: number) => Promise<void>;
    onAddItem: (item: { customItemName: string }) => Promise<void>;
    onUpdateItem: (itemId: number, updates: Partial<ShoppingListItem>) => Promise<void>;
    onRemoveItem: (itemId: number) => Promise<void>;
}

export const ShoppingListComponent: React.FC<ShoppingListComponentProps> = ({ user, lists, activeListId, onSelectList, onCreateList, onDeleteList, onAddItem, onUpdateItem, onRemoveItem }) => {
    const [isCreatingList, setIsCreatingList] = useState(false);
    const [customItemName, setCustomItemName] = useState('');
    const [isAddingCustom, setIsAddingCustom] = useState(false);
    const [isReadingAloud, setIsReadingAloud] = useState(false);

    const activeList = useMemo(() => lists.find(list => list.shopping_list_id === activeListId), [lists, activeListId]);
    const { neededItems, purchasedItems } = useMemo(() => {
        if (!activeList) return { neededItems: [], purchasedItems: [] };
        const neededItems: ShoppingListItem[] = [];
        const purchasedItems: ShoppingListItem[] = [];
        activeList.items.forEach(item => {
            if (item.is_purchased) {
                purchasedItems.push(item);
            } else {
                neededItems.push(item);
            }
        });
        return { neededItems, purchasedItems };
    }, [activeList]);

    const handleCreateList = async () => {
        const name = prompt("Enter a name for your new shopping list:");
        if (name && name.trim()) {
            setIsCreatingList(true);
            await onCreateList(name.trim());
            setIsCreatingList(false);
        }
    };
    
    const handleDeleteList = async () => {
        if (activeList && window.confirm(`Are you sure you want to delete the "${activeList.name}" list? This cannot be undone.`)) {
            await onDeleteList(activeList.shopping_list_id);
        }
    };

    const handleAddCustomItem = async (e: React.FormEvent) => {
        e.preventDefault();
        if (!customItemName.trim()) return;
        setIsAddingCustom(true);
        await onAddItem({ customItemName: customItemName.trim() });
        setCustomItemName('');
        setIsAddingCustom(false);
    };

    const handleReadAloud = useCallback(async () => {
        if (!activeList || neededItems.length === 0) return;
        
        setIsReadingAloud(true);
        try {
            const listText = "Here is your shopping list: " + neededItems.map(item => item.custom_item_name || item.master_item?.name).join(', ');
            const response = await generateSpeechFromText(listText);
            const base64Audio: string = await response.json();
            
            // Play the audio
            const audioContext = new (window.AudioContext)();
            const audioBuffer = await decodeAudioData(decode(base64Audio), audioContext, 24000, 1);
            const source = audioContext.createBufferSource();
            source.buffer = audioBuffer;
            source.connect(audioContext.destination);
            source.start();
        } catch (e) {
            // This is a type-safe way to handle errors. We check if the caught
            // object is an instance of Error before accessing its message property.
            const errorMessage = e instanceof Error ? e.message : 'An unknown error occurred while generating audio.';
            logger.error("Failed to read list aloud", { error: e });
            alert(`Could not read list aloud: ${errorMessage}`);
        } finally {
            setIsReadingAloud(false);
        }
    }, [activeList, neededItems]);

    if (!user) {
        return (
            <div className="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 p-4 text-center">
                <div className="flex flex-col items-center justify-center h-full min-h-[150px]">
                    <UserIcon className="w-10 h-10 text-gray-400 mb-3" />
                    <h4 className="font-semibold text-gray-700 dark:text-gray-300">Your Shopping Lists</h4>
                    <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                        Please log in to manage your shopping lists.
                    </p>
                </div>
            </div>
        );
    }

    return (
        <div className="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 p-4">
            <div className="flex items-center justify-between mb-3">
                <h3 className="text-lg font-bold text-gray-800 dark:text-white flex items-center">
                    <ListBulletIcon className="w-6 h-6 mr-2 text-brand-primary" />
                    Shopping List
                </h3>
                <button 
                    onClick={handleReadAloud} 
                    disabled={isReadingAloud || !activeList || neededItems.length === 0}
                    className="p-1.5 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700/50 text-gray-500 dark:text-gray-400 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
                    title="Read list aloud"
                >
                    {isReadingAloud ? <div className="w-5 h-5"><LoadingSpinner/></div> : <SpeakerWaveIcon className="w-5 h-5" />}
                </button>
            </div>

            <div className="space-y-3 mb-4">
                {lists.length > 0 && (
                     <select
                        value={activeListId || ''}
                        onChange={(e) => onSelectList(Number(e.target.value))}
                        className="block w-full pl-3 pr-8 py-2 text-sm bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-brand-primary focus:border-brand-primary"
                    >
                        {lists.map(list => <option key={list.shopping_list_id} value={list.shopping_list_id}>{list.name}</option>)}
                    </select>
                )}
                <div className="flex space-x-2">
                    <button onClick={handleCreateList} disabled={isCreatingList} className="flex-1 text-sm bg-gray-200 hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600 font-semibold py-2 px-3 rounded-md transition-colors">
                        New List
                    </button>
                    <button onClick={handleDeleteList} disabled={!activeList} className="flex-1 text-sm bg-red-100 hover:bg-red-200 text-red-700 dark:bg-red-900/40 dark:hover:bg-red-900/60 dark:text-red-300 font-semibold py-2 px-3 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed">
                        Delete List
                    </button>
                </div>
            </div>
            
            {activeList ? (
                <>
                    <form onSubmit={handleAddCustomItem} className="flex space-x-2 mb-4">
                        <input
                            type="text"
                            value={customItemName}
                            onChange={(e) => setCustomItemName(e.target.value)}
                            placeholder="Add a custom item..."
                            className="grow block w-full px-3 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm sm:text-sm"
                            disabled={isAddingCustom}
                        />
                         <button type="submit" disabled={isAddingCustom || !customItemName.trim()} className="bg-brand-secondary hover:bg-brand-dark disabled:bg-gray-400 text-white font-bold py-2 px-3 rounded-lg flex items-center justify-center">
                            {isAddingCustom ? <div className="w-5 h-5"><LoadingSpinner /></div> : 'Add'}
                        </button>
                    </form>

                    <div className="space-y-2 max-h-80 overflow-y-auto">
                        {neededItems.length > 0 ? neededItems.map(item => (
                             <div key={item.shopping_list_item_id} className="group flex items-center space-x-2 text-sm">
                                <input
                                    type="checkbox"
                                    checked={item.is_purchased}
                                    onChange={() => onUpdateItem(item.shopping_list_item_id, { is_purchased: !item.is_purchased })}
                                    className="h-4 w-4 rounded border-gray-300 text-brand-primary focus:ring-brand-secondary"
                                />
                                <span className="grow text-gray-800 dark:text-gray-200">{item.custom_item_name || item.master_item?.name}</span>
                                <button onClick={() => onRemoveItem(item.shopping_list_item_id)} className="opacity-0 group-hover:opacity-100 text-red-500 hover:text-red-700 p-1">
                                    <TrashIcon className="w-4 h-4"/>
                                </button>
                            </div>
                        )) : (
                            <p className="text-sm text-gray-500 text-center py-4">This list is empty.</p>
                        )}

                        {purchasedItems.length > 0 && (
                            <div className="pt-4 mt-4 border-t border-gray-200 dark:border-gray-700">
                                <h4 className="text-xs font-semibold text-gray-500 uppercase mb-2">Purchased</h4>
                                {purchasedItems.map(item => (
                                    <div key={item.shopping_list_item_id} className="group flex items-center space-x-2 text-sm">
                                        <input
                                            type="checkbox"
                                            checked={item.is_purchased}
                                            onChange={() => onUpdateItem(item.shopping_list_item_id, { is_purchased: !item.is_purchased })}
                                            className="h-4 w-4 rounded border-gray-300 text-brand-primary focus:ring-brand-secondary"
                                        />
                                        <span className="grow text-gray-500 dark:text-gray-400 line-through">{item.custom_item_name || item.master_item?.name}</span>
                                        <button onClick={() => onRemoveItem(item.shopping_list_item_id)} className="opacity-0 group-hover:opacity-100 text-red-500 hover:text-red-700 p-1">
                                            <TrashIcon className="w-4 h-4"/>
                                        </button>
                                    </div>
                                ))}
                            </div>
                        )}
                    </div>
                </>
            ) : (
                <div className="text-center py-10">
                    <p className="text-gray-500">No shopping lists found. Create one to get started!</p>
                </div>
            )}

        </div>
    );
};