'use client';

import { useState, useRef, useEffect } from 'react';

// Function to generate a random ID
function generateRandomId(existingIds: string[]): string {
    const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
    const length = 8;
    let result: string;

    do {
        result = '';
        for (let i = 0; i < length; i++) {
            result += characters.charAt(Math.floor(Math.random() * characters.length));
        }
    } while (existingIds.includes(result));

    return result;
}

interface VoteOptionsManagerProps {
    voteOptions: { id: string; label: string }[];
    onVoteOptionsChange: (newOptions: { id: string; label: string }[]) => void;
}

export default function VoteOptionsManager({ voteOptions, onVoteOptionsChange }: VoteOptionsManagerProps) {
    const [showVoteOptions, setShowVoteOptions] = useState(false);
    const [newOptionId, setNewOptionId] = useState('');
    const [newOptionLabel, setNewOptionLabel] = useState('');
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [editingOptionId, setEditingOptionId] = useState<string | null>(null);
    const [editedLabel, setEditedLabel] = useState('');
    const editInputRef = useRef<HTMLInputElement>(null);
    const labelInputRef = useRef<HTMLInputElement>(null);

    // Generate a random ID when the component mounts or when the form is reset
    useEffect(() => {
        if (!newOptionId && voteOptions) {
            const existingIds = voteOptions.map(option => option.id);
            setNewOptionId(generateRandomId(existingIds));
        }
    }, [newOptionId, voteOptions]);

    // Add a new vote option
    const handleAddVoteOption = async () => {
        if (!newOptionId || !newOptionLabel) {
            setError('Bitte geben Sie sowohl eine ID als auch ein Label für die neue Option ein');
            return;
        }

        // Check if ID already exists
        if (voteOptions.some(option => option.id === newOptionId)) {
            setError('Eine Option mit dieser ID existiert bereits');
            return;
        }

        setIsLoading(true);
        setError(null);

        try {
            // Add to local state
            const updatedOptions = [...voteOptions, { id: newOptionId, label: newOptionLabel }];

            // Save to server
            const response = await fetch('/api/editable-text', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    id: 'vote-options',
                    content: updatedOptions
                }),
            });

            if (!response.ok) {
                throw new Error('Fehler beim Speichern der Abstimmungsoptionen');
            }

            // Update parent component state
            onVoteOptionsChange(updatedOptions);

            // Reset form and generate a new random ID
            setNewOptionLabel('');
            const existingIds = updatedOptions.map(option => option.id);
            setNewOptionId(generateRandomId(existingIds));
        } catch (err) {
            setError(err instanceof Error ? err.message : 'Ein Fehler ist aufgetreten');
        } finally {
            setIsLoading(false);
        }
    };

    // Start editing a vote option
    const handleEditVoteOption = (option: { id: string; label: string }) => {
        setEditingOptionId(option.id);
        setEditedLabel(option.label);
        // Focus the input field after it's rendered
        setTimeout(() => {
            if (editInputRef.current) {
                editInputRef.current.focus();
            }
        }, 0);
    };

    // Save the edited vote option
    const handleSaveVoteOption = async () => {
        if (!editingOptionId || !editedLabel.trim()) {
            setError('Das Label darf nicht leer sein');
            return;
        }

        setIsLoading(true);
        setError(null);

        try {
            // Update in local state
            const updatedOptions = voteOptions.map(option =>
                option.id === editingOptionId
                    ? { ...option, label: editedLabel.trim() }
                    : option
            );

            // Save to server
            const response = await fetch('/api/editable-text', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    id: 'vote-options',
                    content: updatedOptions
                }),
            });

            if (!response.ok) {
                throw new Error('Fehler beim Speichern der Abstimmungsoptionen');
            }

            // Update parent component state
            onVoteOptionsChange(updatedOptions);

            // Exit edit mode
            setEditingOptionId(null);
        } catch (err) {
            setError(err instanceof Error ? err.message : 'Ein Fehler ist aufgetreten');
        } finally {
            setIsLoading(false);
        }
    };

    // Cancel editing
    const handleCancelEdit = () => {
        setEditingOptionId(null);
    };

    // Move option up in the list
    const handleMoveOptionUp = async (index: number) => {
        if (index <= 0) return; // Already at the top

        setIsLoading(true);
        setError(null);

        try {
            // Create a new array with the option moved up
            const updatedOptions = [...voteOptions];
            [updatedOptions[index - 1], updatedOptions[index]] = [updatedOptions[index], updatedOptions[index - 1]];

            // Save to server
            const response = await fetch('/api/editable-text', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    id: 'vote-options',
                    content: updatedOptions
                }),
            });

            if (!response.ok) {
                throw new Error('Fehler beim Speichern der Abstimmungsoptionen');
            }

            // Update parent component state
            onVoteOptionsChange(updatedOptions);
        } catch (err) {
            setError(err instanceof Error ? err.message : 'Ein Fehler ist aufgetreten');
        } finally {
            setIsLoading(false);
        }
    };

    // Move option down in the list
    const handleMoveOptionDown = async (index: number) => {
        if (index >= voteOptions.length - 1) return; // Already at the bottom

        setIsLoading(true);
        setError(null);

        try {
            // Create a new array with the option moved down
            const updatedOptions = [...voteOptions];
            [updatedOptions[index], updatedOptions[index + 1]] = [updatedOptions[index + 1], updatedOptions[index]];

            // Save to server
            const response = await fetch('/api/editable-text', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    id: 'vote-options',
                    content: updatedOptions
                }),
            });

            if (!response.ok) {
                throw new Error('Fehler beim Speichern der Abstimmungsoptionen');
            }

            // Update parent component state
            onVoteOptionsChange(updatedOptions);
        } catch (err) {
            setError(err instanceof Error ? err.message : 'Ein Fehler ist aufgetreten');
        } finally {
            setIsLoading(false);
        }
    };

    // Remove a vote option
    const handleRemoveVoteOption = async (optionId: string) => {
        // Don't allow removing if there are less than 2 options
        if (voteOptions.length <= 1) {
            setError('Es muss mindestens eine Abstimmungsoption vorhanden sein');
            return;
        }

        // Show confirmation dialog
        const optionToRemove = voteOptions.find(option => option.id === optionId);
        if (!confirm(`Sind Sie sicher, dass Sie die Option "${optionToRemove?.label}" entfernen möchten? Bestehende Abstimmungen mit dieser Option werden nicht gelöscht, aber in den Statistiken möglicherweise nicht mehr korrekt angezeigt.`)) {
            return;
        }

        setIsLoading(true);
        setError(null);

        try {
            // Remove from local state
            const updatedOptions = voteOptions.filter(option => option.id !== optionId);

            // Save to server
            const response = await fetch('/api/editable-text', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    id: 'vote-options',
                    content: updatedOptions
                }),
            });

            if (!response.ok) {
                throw new Error('Fehler beim Speichern der Abstimmungsoptionen');
            }

            // Update parent component state
            onVoteOptionsChange(updatedOptions);
        } catch (err) {
            setError(err instanceof Error ? err.message : 'Ein Fehler ist aufgetreten');
        } finally {
            setIsLoading(false);
        }
    };

    return (
        <div className="mb-6">
            <div className="flex justify-between items-center mb-4">
                <h2 className="text-xl font-bold text-[#0057a6]">Abstimmungsoptionen</h2>
                <button
                    onClick={() => setShowVoteOptions(!showVoteOptions)}
                    className="text-sm text-[#0057a6] hover:underline"
                >
                    {showVoteOptions ? 'Ausblenden' : 'Bearbeiten'}
                </button>
            </div>

            {showVoteOptions && (
                <div className="bg-[#e6f0fa] p-4 mb-4">
                    <h3 className="font-medium text-[#0057a6] mb-3">Aktuelle Optionen</h3>

                    <div className="space-y-2 mb-4">
                        {voteOptions.map((option, index) => (
                            <div key={option.id} className="flex items-center justify-between p-2 bg-white">
                                <div className="flex items-center space-x-2">
                                    <div className="flex flex-col">
                                        <button
                                            onClick={() => handleMoveOptionUp(index)}
                                            className="text-gray-600 hover:text-gray-800 disabled:opacity-30"
                                            disabled={index === 0}
                                            title="Nach oben verschieben"
                                        >
                                            ▲
                                        </button>
                                        <button
                                            onClick={() => handleMoveOptionDown(index)}
                                            className="text-gray-600 hover:text-gray-800 disabled:opacity-30"
                                            disabled={index === voteOptions.length - 1}
                                            title="Nach unten verschieben"
                                        >
                                            ▼
                                        </button>
                                    </div>
                                    <div>
                                        {editingOptionId === option.id ? (
                                            <div className="flex items-center">
                                                <span className="font-medium mr-2">{option.id}:</span>
                                                <input
                                                    ref={editInputRef}
                                                    type="text"
                                                    value={editedLabel}
                                                    onChange={(e) => setEditedLabel(e.target.value)}
                                                    className="px-2 py-1 border border-gray-300 focus:outline-none focus:border-[#0057a6]"
                                                    onKeyDown={(e) => {
                                                        if (e.key === 'Enter') handleSaveVoteOption();
                                                        if (e.key === 'Escape') handleCancelEdit();
                                                    }}
                                                />
                                                <button
                                                    onClick={handleSaveVoteOption}
                                                    className="ml-2 text-green-600 hover:text-green-800"
                                                    title="Speichern"
                                                >
                                                    ✓
                                                </button>
                                                <button
                                                    onClick={handleCancelEdit}
                                                    className="ml-1 text-gray-600 hover:text-gray-800"
                                                    title="Abbrechen"
                                                >
                                                    ✕
                                                </button>
                                            </div>
                                        ) : (
                                            <div>
                                                <span className="font-medium">{option.id}:</span> {option.label}
                                            </div>
                                        )}
                                    </div>
                                </div>
                                <div className="flex space-x-2">
                                    {editingOptionId !== option.id && (
                                        <button
                                            onClick={() => handleEditVoteOption(option)}
                                            className="text-blue-600 hover:text-blue-800"
                                            title="Option bearbeiten"
                                        >
                                            ✎
                                        </button>
                                    )}
                                    <button
                                        onClick={() => handleRemoveVoteOption(option.id)}
                                        className="text-red-600 hover:text-red-800"
                                        title="Option entfernen"
                                    >
                                        ✕
                                    </button>
                                </div>
                            </div>
                        ))}
                    </div>

                    <h3 className="font-medium text-[#0057a6] mb-2">Neue Option hinzufügen</h3>
                    <div className="space-y-3">
                        <div>
                            <label htmlFor="newOptionId" className="block text-sm font-medium text-gray-700 mb-1">
                                Option ID (z.B. &quot;yes&quot;, &quot;no&quot;)
                            </label>
                            <input
                                type="text"
                                id="newOptionId"
                                value={newOptionId}
                                onChange={(e) => setNewOptionId(e.target.value)}
                                className="w-full px-3 py-2 border border-gray-300 focus:outline-none focus:border-[#0057a6]"
                                placeholder="option-id"
                            />
                            <p className="text-xs text-gray-500 mt-1">
                                Die ID wird intern verwendet und sollte kurz und eindeutig sein.
                            </p>
                        </div>

                        <div>
                            <label htmlFor="newOptionLabel" className="block text-sm font-medium text-gray-700 mb-1">
                                Anzeigename
                            </label>
                            <input
                                type="text"
                                id="newOptionLabel"
                                ref={labelInputRef}
                                value={newOptionLabel}
                                onChange={(e) => setNewOptionLabel(e.target.value)}
                                className="w-full px-3 py-2 border border-gray-300 focus:outline-none focus:border-[#0057a6]"
                                placeholder="Anzeigename der Option"
                                onFocus={() => {
                                    // Generate a random ID if the field is empty
                                    if (!newOptionId) {
                                        const existingIds = voteOptions.map(option => option.id);
                                        setNewOptionId(generateRandomId(existingIds));
                                    }
                                }}
                            />
                            <p className="text-xs text-gray-500 mt-1">
                                Der Anzeigename wird den Abstimmenden angezeigt.
                            </p>
                        </div>

                        {error && (
                            <div className="text-red-500 text-sm">{error}</div>
                        )}

                        <button
                            onClick={handleAddVoteOption}
                            disabled={isLoading}
                            className="ssvc-button w-full disabled:opacity-50"
                        >
                            {isLoading ? 'Wird hinzugefügt...' : 'Option hinzufügen'}
                        </button>
                    </div>

                    <div className="mt-4 text-sm text-gray-600">
                        <p className="font-medium">Hinweis:</p>
                        <p>Das Ändern der Abstimmungsoptionen wirkt sich nur auf neue Abstimmungen aus. Bestehende Abstimmungsdaten bleiben unverändert.</p>
                    </div>
                </div>
            )}
        </div>
    );
}
