import { useCallback, useEffect, useState } from 'react';
import MicIcon from '@mui/icons-material/Mic';
import MicOffIcon from '@mui/icons-material/MicOff';
import api from '../services/api';
import GaugeScore from '@/components/graphs/GaugeScore';
import TypographyAnimated from '@/components/ui/TypographyAnimated';
import AppButton from '@/components/ui/Button';
import { useTrainingSpeechRecognition } from '@/hooks/useTrainingSpeechRecognition';
import { useLocale } from '@/context/LocaleContext';
import { Box, CircularProgress, TextField, Typography } from '@mui/material';

const INDICATORS_PATH = import.meta.env.VITE_INDICATORS_ENDPOINT ?? '/api/indicators';
const TRAINING_EVALUATE_PATH =
    import.meta.env.VITE_TRAINING_EVALUATE_ENDPOINT ?? '/api/training/evaluate';

type TypeIndicator = {
    id: number;
    name: string;
    orden: number;
};

type IndicatorsPaginated = {
    data: TypeIndicator[];
};

type TrainingScoreRow = {
    id: number;
    nivel: number;
};

type TrainingEvaluateResponse = {
    scores: TrainingScoreRow[];
};

const DEFAULT_SILENCE_MS = 2000;

export default function Training() {
    const { t } = useLocale();
    const [indicators, setIndicators] = useState<TypeIndicator[]>([]);
    const [scores, setScores] = useState<Record<number, number>>({});
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);
    const [evaluating, setEvaluating] = useState(false);
    const [evaluateError, setEvaluateError] = useState<string | null>(null);
    const [silenceMs, setSilenceMs] = useState(
        Number(import.meta.env.VITE_TRAINING_SILENCE_MS) || DEFAULT_SILENCE_MS,
    );

    const evaluateFragment = useCallback(async (text: string) => {
        setEvaluating(true);
        setEvaluateError(null);
        try {
            const { data } = await api.post<TrainingEvaluateResponse>(TRAINING_EVALUATE_PATH, {
                text,
            });
            setScores((prev) => {
                const next = { ...prev };
                for (const row of data.scores ?? []) {
                    if (row.id > 0) {
                        next[row.id] = row.nivel;
                    }
                }
                return next;
            });
        } catch {
            setEvaluateError(t('training', 'evaluation_failed'));
        } finally {
            setEvaluating(false);
        }
    }, [t]);

    const {
        listening,
        supported,
        interimText,
        pendingText,
        speechError,
        toggleListening,
    } = useTrainingSpeechRecognition({
        silenceMs,
        onSilence: evaluateFragment,
    });

    useEffect(() => {
        let cancelled = false;
        (async () => {
            setLoading(true);
            setError(null);
            try {
                const { data } = await api.get<IndicatorsPaginated>(INDICATORS_PATH, {
                    params: { per_page: 100 },
                });
                if (!cancelled) {
                    setIndicators(
                        [...(data.data ?? [])].sort((a, b) => (a.orden ?? 0) - (b.orden ?? 0)),
                    );
                }
            } catch {
                if (!cancelled) {
                    setError('No se pudieron cargar los indicadores.');
                    setIndicators([]);
                }
            } finally {
                if (!cancelled) {
                    setLoading(false);
                }
            }
        })();
        return () => {
            cancelled = true;
        };
    }, []);

    const liveTranscript = `${pendingText}${interimText}`.trim();
    const speechErrorMessage =
        speechError === 'permission_denied'
            ? t('training', 'speech_permission_denied')
            : speechError
              ? String(speechError)
              : null;

    return (
        <div className="container-fluid w-full space-y-6 py-4">
            <TypographyAnimated
                variant="subtitle2"
                prefix={t('training', 'top_heading_prefix')}
                rotatingWords={t('training', 'top_heading_rotating')
                    .split('|')
                    .map((s) => s.trim())
                    .filter(Boolean)}
                sx={{
                    color: 'text.primary',
                    fontWeight: 600,
                    textTransform: 'uppercase',
                    letterSpacing: '0.18em',
                    fontSize: '1.3rem',
                }}
            />

            {loading && (
                <p className="text-sm text-zinc-600 dark:text-zinc-400">Cargando…</p>
            )}
            {!loading && error && (
                <p className="text-sm text-red-600">{error}</p>
            )}
            {!loading && !error && indicators.length === 0 && (
                <p className="text-sm text-zinc-600 dark:text-zinc-400">
                    No hay indicadores configurados.
                </p>
            )}

            {!loading && indicators.length > 0 && (
                <div className="grid w-full grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4 mt-3">
                    {indicators.map((indicator) => (
                        <Box
                            key={indicator.id}
                            sx={{
                                display: 'flex',
                                flexDirection: 'column',
                                alignItems: 'center',
                                justifyContent: 'center',
                                border: 1,
                                borderColor: 'divider',
                                borderRadius: 2,
                                px: 1.5,
                                py: 2,
                                minWidth: 0,
                            }}
                        >
                            <GaugeScore
                                value={scores[indicator.id] ?? 0}
                                aria-label={indicator.name}
                                activeColor="#00D8FF"
                                inactiveColor="#9ca3af"
                                footer={
                                    <Typography
                                        variant="caption"
                                        sx={{
                                            display: 'block',
                                            fontWeight: 700,
                                            textTransform: 'uppercase',
                                            letterSpacing: '0.06em',
                                            color: 'text.secondary',
                                        }}
                                    >
                                        {indicator.name}
                                    </Typography>
                                }
                            />
                        </Box>
                    ))}
                </div>
            )}

            {!loading && indicators.length > 0 && (
                <Box
                    sx={{
                        display: 'flex',
                        flexDirection: 'column',
                        alignItems: 'center',
                        gap: 2,
                        pt: 2,
                        width: '100%',
                    }}
                >
                    <TextField
                        type="number"
                        size="small"
                        label={t('training', 'silence_ms_label')}
                        value={silenceMs}
                        onChange={(e) => {
                            const n = Number(e.target.value);
                            if (Number.isFinite(n)) {
                                setSilenceMs(Math.min(10000, Math.max(500, Math.round(n))));
                            }
                        }}
                        disabled={listening}
                        inputProps={{ min: 500, max: 10000, step: 100 }}
                        sx={{ width: { xs: '100%', sm: 220 } }}
                    />

                    {(liveTranscript || evaluating) && (
                        <Box sx={{ textAlign: 'center', maxWidth: 560, px: 2 }}>
                            {liveTranscript ? (
                                <Typography variant="body2" color="text.secondary">
                                    {liveTranscript}
                                </Typography>
                            ) : null}
                            {evaluating ? (
                                <Box
                                    sx={{
                                        display: 'flex',
                                        alignItems: 'center',
                                        justifyContent: 'center',
                                        gap: 1,
                                        mt: 1,
                                    }}
                                >
                                    <CircularProgress size={18} />
                                    <Typography variant="caption" color="text.secondary">
                                        {t('training', 'evaluating')}
                                    </Typography>
                                </Box>
                            ) : null}
                        </Box>
                    )}

                    {!supported ? (
                        <Typography color="error" variant="body2">
                            {t('training', 'speech_not_supported')}
                        </Typography>
                    ) : (
                        <AppButton
                            type="button"
                            onClick={toggleListening}
                            disabled={evaluating && !listening}
                            startIcon={listening ? <MicOffIcon /> : <MicIcon />}
                            sx={{ minWidth: 280 }}
                        >
                            {listening
                                ? t('training', 'stop_microphone')
                                : t('training', 'start_microphone')}
                        </AppButton>
                    )}

                    {speechErrorMessage ? (
                        <Typography color="error" variant="body2">
                            {speechErrorMessage}
                        </Typography>
                    ) : null}
                    {evaluateError ? (
                        <Typography color="error" variant="body2">
                            {evaluateError}
                        </Typography>
                    ) : null}
                </Box>
            )}
        </div>
    );
}
