/**
 * SpeechSettings Component
 *
 * Settings page for configuring speech preferences per workspace.
 * Includes STT settings, TTS settings, voice preview, and provider status.
 *
 * Follows PDA-friendly design: calm colors, no aggressive language.
 *
 * Issue #404
 */

"use client";

import { useState, useEffect, useCallback } from "react";
import type { ReactElement } from "react";
import { Card, CardHeader, CardContent, CardTitle, CardDescription } from "@/components/ui/card";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Slider } from "@/components/ui/slider";
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from "@/components/ui/select";
import { getVoices, getHealthStatus } from "@/lib/api/speech";
import type { VoiceInfo, HealthResponse } from "@/lib/api/speech";
import { useTextToSpeech } from "@/hooks/useTextToSpeech";

/** Supported languages for STT */
const STT_LANGUAGES = [
  { value: "en", label: "English" },
  { value: "es", label: "Spanish" },
  { value: "fr", label: "French" },
  { value: "de", label: "German" },
  { value: "it", label: "Italian" },
  { value: "pt", label: "Portuguese" },
  { value: "ja", label: "Japanese" },
  { value: "zh", label: "Chinese" },
  { value: "ko", label: "Korean" },
  { value: "auto", label: "Auto-detect" },
];

/** TTS tier options */
const TIER_OPTIONS = [
  { value: "default", label: "Default" },
  { value: "premium", label: "Premium" },
  { value: "fallback", label: "Fallback" },
];

/** Sample text for voice preview */
const PREVIEW_TEXT = "Hello, this is a preview of the selected voice. How does it sound?";

/**
 * SpeechSettings provides a comprehensive settings interface for
 * configuring speech-to-text and text-to-speech preferences.
 */
export function SpeechSettings(): ReactElement {
  // STT state
  const [sttEnabled, setSttEnabled] = useState(true);
  const [sttLanguage, setSttLanguage] = useState("en");

  // TTS state
  const [ttsEnabled, setTtsEnabled] = useState(true);
  const [selectedVoice, setSelectedVoice] = useState("");
  const [selectedTier, setSelectedTier] = useState("default");
  const [autoPlay, setAutoPlay] = useState(false);
  const [speed, setSpeed] = useState(1.0);

  // Data state
  const [voices, setVoices] = useState<VoiceInfo[]>([]);
  const [voicesError, setVoicesError] = useState<string | null>(null);
  const [healthData, setHealthData] = useState<HealthResponse["data"] | null>(null);
  const [healthError, setHealthError] = useState<string | null>(null);

  // Preview hook
  const {
    synthesize,
    audioUrl,
    isLoading: isPreviewLoading,
    error: previewError,
  } = useTextToSpeech();

  /**
   * Fetch available voices from the API
   */
  const fetchVoices = useCallback(async (): Promise<void> => {
    try {
      setVoicesError(null);
      const response = await getVoices();
      setVoices(response.data);

      // Select the first default voice if none selected
      if (response.data.length > 0 && !selectedVoice) {
        const defaultVoice = response.data.find((v) => v.isDefault);
        const firstVoice = response.data[0];
        setSelectedVoice(defaultVoice?.id ?? firstVoice?.id ?? "");
      }
    } catch {
      setVoicesError("Unable to load voices. Please try again later.");
    }
  }, [selectedVoice]);

  /**
   * Fetch health status from the API
   */
  const fetchHealth = useCallback(async (): Promise<void> => {
    try {
      setHealthError(null);
      const response = await getHealthStatus();
      setHealthData(response.data);
    } catch {
      setHealthError("Unable to check provider status. Please try again later.");
    }
  }, []);

  // Fetch voices and health on mount
  useEffect(() => {
    void fetchVoices();
    void fetchHealth();
  }, [fetchVoices, fetchHealth]);

  /**
   * Handle voice preview test
   */
  const handleTestVoice = useCallback(async (): Promise<void> => {
    const options: Record<string, string | number> = {
      speed,
      tier: selectedTier,
    };
    if (selectedVoice) {
      options.voice = selectedVoice;
    }
    await synthesize(PREVIEW_TEXT, options);
  }, [synthesize, selectedVoice, speed, selectedTier]);

  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-2xl font-semibold text-gray-900">Speech Settings</h2>
        <p className="text-sm text-gray-600 mt-1">
          Configure voice input and output preferences for your workspace
        </p>
      </div>

      {/* STT Settings */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Speech-to-Text</CardTitle>
          <CardDescription>Configure voice input preferences</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="space-y-4">
            {/* Enable STT Toggle */}
            <div className="flex items-center justify-between">
              <div className="space-y-0.5">
                <Label htmlFor="stt-enabled">Enable Speech-to-Text</Label>
                <p className="text-xs text-gray-500">
                  Allow voice input for text fields and commands
                </p>
              </div>
              <Switch
                id="stt-enabled"
                checked={sttEnabled}
                onCheckedChange={setSttEnabled}
                aria-label="Enable Speech-to-Text"
              />
            </div>

            {/* Language Preference */}
            <div className="space-y-2">
              <Label htmlFor="stt-language">Language</Label>
              <Select value={sttLanguage} onValueChange={setSttLanguage}>
                <SelectTrigger id="stt-language" className="w-full">
                  <SelectValue placeholder="Select language" />
                </SelectTrigger>
                <SelectContent>
                  {STT_LANGUAGES.map((lang) => (
                    <SelectItem key={lang.value} value={lang.value}>
                      {lang.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* TTS Settings */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Text-to-Speech</CardTitle>
          <CardDescription>Configure voice output preferences</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="space-y-4">
            {/* Enable TTS Toggle */}
            <div className="flex items-center justify-between">
              <div className="space-y-0.5">
                <Label htmlFor="tts-enabled">Enable Text-to-Speech</Label>
                <p className="text-xs text-gray-500">
                  Allow reading content aloud with synthesized voice
                </p>
              </div>
              <Switch
                id="tts-enabled"
                checked={ttsEnabled}
                onCheckedChange={setTtsEnabled}
                aria-label="Enable Text-to-Speech"
              />
            </div>

            {/* Default Voice Selector */}
            <div className="space-y-2">
              <Label htmlFor="tts-voice">Default Voice</Label>
              {voicesError ? (
                <p className="text-sm text-amber-600">{voicesError}</p>
              ) : (
                <Select value={selectedVoice} onValueChange={setSelectedVoice}>
                  <SelectTrigger id="tts-voice" className="w-full">
                    <SelectValue placeholder="Select a voice" />
                  </SelectTrigger>
                  <SelectContent>
                    {voices.map((voice) => (
                      <SelectItem key={voice.id} value={voice.id}>
                        {voice.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              )}
            </div>

            {/* Provider Tier Preference */}
            <div className="space-y-2">
              <Label htmlFor="tts-tier">Provider Tier</Label>
              <p className="text-xs text-gray-500">
                Choose the preferred quality tier for voice synthesis
              </p>
              <Select value={selectedTier} onValueChange={setSelectedTier}>
                <SelectTrigger id="tts-tier" className="w-full">
                  <SelectValue placeholder="Select tier" />
                </SelectTrigger>
                <SelectContent>
                  {TIER_OPTIONS.map((tier) => (
                    <SelectItem key={tier.value} value={tier.value}>
                      {tier.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            {/* Auto-play Toggle */}
            <div className="flex items-center justify-between">
              <div className="space-y-0.5">
                <Label htmlFor="tts-autoplay">Auto-play</Label>
                <p className="text-xs text-gray-500">
                  Automatically play TTS responses when received
                </p>
              </div>
              <Switch
                id="tts-autoplay"
                checked={autoPlay}
                onCheckedChange={setAutoPlay}
                aria-label="Auto-play"
              />
            </div>

            {/* Speed Control */}
            <div className="space-y-2">
              <div className="flex items-center justify-between">
                <Label htmlFor="tts-speed">Speed</Label>
                <span className="text-sm text-gray-600">{speed.toFixed(1)}x</span>
              </div>
              <Slider
                id="tts-speed"
                min={0.5}
                max={2}
                step={0.1}
                value={[speed]}
                onValueChange={(values) => {
                  const newSpeed = values[0];
                  if (newSpeed !== undefined) {
                    setSpeed(newSpeed);
                  }
                }}
              />
              <div className="flex justify-between text-xs text-gray-400">
                <span>0.5x</span>
                <span>1.0x</span>
                <span>2.0x</span>
              </div>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Voice Preview */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Voice Preview</CardTitle>
          <CardDescription>Preview the selected voice with sample text</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="space-y-3">
            <p className="text-sm text-gray-600 italic">&ldquo;{PREVIEW_TEXT}&rdquo;</p>
            <Button
              variant="outline"
              size="sm"
              onClick={() => void handleTestVoice()}
              disabled={isPreviewLoading}
              aria-label="Test voice"
            >
              {isPreviewLoading ? "Synthesizing..." : "Test Voice"}
            </Button>
            {previewError && <p className="text-sm text-amber-600">{previewError}</p>}
            {audioUrl && (
              <audio controls src={audioUrl} className="w-full mt-2">
                <track kind="captions" />
              </audio>
            )}
          </div>
        </CardContent>
      </Card>

      {/* Provider Status */}
      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Provider Status</CardTitle>
          <CardDescription>Current availability of speech service providers</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="space-y-3" data-testid="provider-status">
            {healthError ? (
              <p className="text-sm text-amber-600">{healthError}</p>
            ) : healthData ? (
              <>
                {/* STT Provider */}
                <div className="flex items-center justify-between py-2">
                  <span className="text-sm text-gray-700">Speech-to-Text Provider</span>
                  <div className="flex items-center gap-2">
                    {healthData.stt.available ? (
                      <>
                        <span
                          className="inline-block h-2.5 w-2.5 rounded-full bg-green-500"
                          data-testid="status-active"
                          aria-label="Active"
                        />
                        <span className="text-sm text-gray-600">Active</span>
                      </>
                    ) : (
                      <>
                        <span
                          className="inline-block h-2.5 w-2.5 rounded-full bg-gray-400"
                          data-testid="status-inactive"
                          aria-label="Inactive"
                        />
                        <span className="text-sm text-gray-600">Inactive</span>
                      </>
                    )}
                  </div>
                </div>

                {/* TTS Provider */}
                <div className="flex items-center justify-between py-2">
                  <span className="text-sm text-gray-700">Text-to-Speech Provider</span>
                  <div className="flex items-center gap-2">
                    {healthData.tts.available ? (
                      <>
                        <span
                          className="inline-block h-2.5 w-2.5 rounded-full bg-green-500"
                          data-testid="status-active"
                          aria-label="Active"
                        />
                        <span className="text-sm text-gray-600">Active</span>
                      </>
                    ) : (
                      <>
                        <span
                          className="inline-block h-2.5 w-2.5 rounded-full bg-gray-400"
                          data-testid="status-inactive"
                          aria-label="Inactive"
                        />
                        <span className="text-sm text-gray-600">Inactive</span>
                      </>
                    )}
                  </div>
                </div>
              </>
            ) : (
              <p className="text-sm text-gray-500">Checking provider status...</p>
            )}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

export default SpeechSettings;
