import { useState, useEffect } from "react";
import { Mic, Settings, Volume2, Info } from "lucide-react";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Badge } from "@/components/ui/badge";
import { useToast } from "@/components/ui/use-toast";
import { showSaveFailureToastIfNeeded } from "@/components/shared";
import { useConfigStore } from "@/store/configStore";
import { VoiceConfig as VoiceConfigType } from "@/types/config";

const OPENAI_TRANSCRIPTION_ENDPOINT =
  "https://api.openai.com/v1/audio/transcriptions";

const DEFAULT_VOICE_CONFIG: VoiceConfigType = {
  enabled: false,
  visible_router_echo: true,
  stt: {
    provider: "openai",
    model: "gpt-4o-transcribe",
    api_key: "",
    host: "",
  },
  intelligence: {
    model: "default",
  },
};

function mergeVoiceConfig(config?: Partial<VoiceConfigType>): VoiceConfigType {
  return {
    ...DEFAULT_VOICE_CONFIG,
    ...config,
    stt: {
      ...DEFAULT_VOICE_CONFIG.stt,
      ...(config?.stt || {}),
    },
    intelligence: {
      ...DEFAULT_VOICE_CONFIG.intelligence,
      ...(config?.intelligence || {}),
    },
  };
}

function normalizeHost(host?: string): string {
  if (!host) return "";
  return host.trim().replace(/\/+$/, "");
}

function speechBaseUrl(host?: string): string {
  const normalized = normalizeHost(host);
  if (!normalized) return "";
  return normalized.endsWith("/v1") ? normalized : `${normalized}/v1`;
}

function normalizeSTTConfig(
  stt: VoiceConfigType["stt"],
): VoiceConfigType["stt"] {
  const normalized = { ...stt };
  const apiKey = stt.api_key?.trim();
  const host = normalizeHost(stt.host);
  if (apiKey) normalized.api_key = apiKey;
  else delete normalized.api_key;
  if (host) normalized.host = host;
  else delete normalized.host;
  return normalized;
}

export function VoiceConfig() {
  const { config, isLoading, saveConfig, updateVoiceConfig } = useConfigStore();
  const { toast } = useToast();

  // Initialize local state with default values if voice config doesn't exist
  const [voiceConfig, setVoiceConfig] = useState<VoiceConfigType>(() =>
    mergeVoiceConfig(config?.voice),
  );

  // Update local state when config changes
  useEffect(() => {
    setVoiceConfig(mergeVoiceConfig(config?.voice));
  }, [config?.voice]);

  const handleVoiceConfigChange = (updates: Partial<VoiceConfigType>) => {
    const newConfig = { ...voiceConfig, ...updates };
    setVoiceConfig(newConfig);

    updateVoiceConfig(newConfig);
  };

  const handleSTTChange = (updates: Partial<VoiceConfigType["stt"]>) => {
    handleVoiceConfigChange({
      stt: { ...voiceConfig.stt, ...updates },
    });
  };

  const handleIntelligenceChange = (
    updates: Partial<VoiceConfigType["intelligence"]>,
  ) => {
    handleVoiceConfigChange({
      intelligence: { ...voiceConfig.intelligence, ...updates },
    });
  };

  // Get available models from config
  const availableModels = config?.models ? Object.keys(config.models) : [];
  const isCompatibleProvider = voiceConfig.stt.provider === "openai_compatible";
  const normalizedBaseUrl = speechBaseUrl(voiceConfig.stt.host);
  const effectiveEndpoint = normalizedBaseUrl
    ? `${normalizedBaseUrl}/audio/transcriptions`
    : isCompatibleProvider
      ? "Base URL required"
      : OPENAI_TRANSCRIPTION_ENDPOINT;
  const effectiveMode =
    normalizedBaseUrl || isCompatibleProvider
      ? "OpenAI-compatible API"
      : "OpenAI API";
  const keySource = voiceConfig.stt.api_key?.trim()
    ? "Stored in voice settings"
    : isCompatibleProvider
      ? "Non-secret compatibility placeholder"
      : "OPENAI_API_KEY environment variable";
  const providerLabel = isCompatibleProvider ? "OpenAI-compatible" : "OpenAI";

  const handleSave = async () => {
    updateVoiceConfig({
      ...voiceConfig,
      stt: normalizeSTTConfig(voiceConfig.stt),
    });
    const result = await saveConfig();
    if (
      showSaveFailureToastIfNeeded(result, {
        staleMessage: "Save was superseded by newer voice configuration edits.",
        fallbackMessage: "Failed to save voice configuration.",
      })
    ) {
      return;
    }
    toast({
      title: "Voice Configuration Saved",
      description: "Your voice settings have been updated successfully.",
    });
  };

  return (
    <div className="space-y-6">
      {/* Main Voice Settings */}
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <Volume2 className="h-5 w-5 text-primary" />
              <CardTitle>Voice Message Support</CardTitle>
            </div>
            <input
              type="checkbox"
              checked={voiceConfig.enabled}
              onChange={(e) =>
                handleVoiceConfigChange({ enabled: e.target.checked })
              }
              className="h-5 w-5 rounded"
            />
          </div>
          <CardDescription>
            Enable automatic transcription and processing of voice messages
          </CardDescription>
        </CardHeader>

        <CardContent className="space-y-6">
          {/* Status Alert */}
          <Alert>
            <Info className="h-4 w-4" />
            <AlertDescription>
              {voiceConfig.enabled
                ? "Voice messages will be automatically transcribed and processed. The router agent handles all voice messages to avoid duplicates."
                : "Voice message handling is currently disabled. You can still review and edit settings below."}
            </AlertDescription>
          </Alert>

          {/* Current Settings Summary */}
          <div className="rounded-lg border border-border bg-muted/40 p-4 shadow-sm">
            <div className="flex flex-wrap items-center justify-between gap-2">
              <h3 className="text-sm font-semibold">
                Current Effective Settings
              </h3>
              <Badge variant={voiceConfig.enabled ? "default" : "secondary"}>
                {voiceConfig.enabled ? "Enabled" : "Disabled"}
              </Badge>
            </div>
            <div className="mt-3 space-y-2 text-sm">
              <div className="flex items-start justify-between gap-4">
                <span className="text-muted-foreground">Mode:</span>
                <span className="font-mono text-right text-foreground">
                  {effectiveMode}
                </span>
              </div>
              <div className="flex items-start justify-between gap-4">
                <span className="text-muted-foreground">Provider:</span>
                <span className="font-mono text-right text-foreground">
                  {providerLabel}
                </span>
              </div>
              <div className="flex items-start justify-between gap-4">
                <span className="text-muted-foreground">STT Model:</span>
                <span className="font-mono text-right text-foreground">
                  {voiceConfig.stt.model}
                </span>
              </div>
              <div className="flex flex-col gap-1 sm:flex-row sm:items-start sm:justify-between sm:gap-4">
                <span className="text-muted-foreground">Endpoint:</span>
                <span className="font-mono text-foreground break-all sm:text-right">
                  {effectiveEndpoint}
                </span>
              </div>
              <div className="flex items-start justify-between gap-4">
                <span className="text-muted-foreground">API Key Source:</span>
                <span className="font-mono text-right text-foreground">
                  {keySource}
                </span>
              </div>
              <div className="flex items-start justify-between gap-4">
                <span className="text-muted-foreground">Command Model:</span>
                <span className="font-mono text-right text-foreground">
                  {voiceConfig.intelligence.model}
                </span>
              </div>
              <div className="flex items-start justify-between gap-4">
                <span className="text-muted-foreground">
                  Visible Router Echo:
                </span>
                <span className="font-mono text-right text-foreground">
                  {voiceConfig.visible_router_echo ? "Enabled" : "Disabled"}
                </span>
              </div>
            </div>
          </div>

          <div className="rounded-lg border border-border bg-background p-4 shadow-sm">
            <div className="flex items-start justify-between gap-4">
              <div className="space-y-1">
                <Label
                  htmlFor="visible-router-echo"
                  className="text-base font-semibold"
                >
                  Visible Router Echo
                </Label>
                <p className="text-sm text-muted-foreground">
                  Post the normalized transcript or fallback text as a
                  display-only router message before any router handoff.
                </p>
              </div>
              <input
                id="visible-router-echo"
                type="checkbox"
                checked={voiceConfig.visible_router_echo}
                onChange={(e) =>
                  handleVoiceConfigChange({
                    visible_router_echo: e.target.checked,
                  })
                }
                className="mt-1 h-5 w-5 rounded"
              />
            </div>
          </div>

          {/* STT Configuration */}
          <div className="space-y-4">
            <div className="flex items-center gap-2">
              <Mic className="h-4 w-4" />
              <Label className="text-base font-semibold">
                Speech-to-Text (STT)
              </Label>
            </div>

            <div className="grid gap-4">
              <div className="space-y-2">
                <Label htmlFor="stt-provider">Provider</Label>
                <Select
                  value={voiceConfig.stt.provider}
                  onValueChange={(
                    provider: VoiceConfigType["stt"]["provider"],
                  ) => handleSTTChange({ provider })}
                >
                  <SelectTrigger id="stt-provider">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="openai">OpenAI</SelectItem>
                    <SelectItem value="openai_compatible">
                      OpenAI-compatible
                    </SelectItem>
                  </SelectContent>
                </Select>
              </div>

              <div className="space-y-2">
                <Label htmlFor="stt-model">Model</Label>
                <Input
                  id="stt-model"
                  value={voiceConfig.stt.model}
                  onChange={(e) => handleSTTChange({ model: e.target.value })}
                  placeholder="gpt-4o-transcribe"
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="stt-api-key">API Key (Optional)</Label>
                <Input
                  id="stt-api-key"
                  type="password"
                  value={voiceConfig.stt.api_key || ""}
                  onChange={(e) => handleSTTChange({ api_key: e.target.value })}
                  placeholder={
                    isCompatibleProvider
                      ? "Optional for local-compatible services"
                      : "Uses OPENAI_API_KEY env var if not set"
                  }
                />
                <p className="text-xs text-muted-foreground">
                  {isCompatibleProvider
                    ? "Leave empty to send a non-secret compatibility placeholder"
                    : "Leave empty to use the OPENAI_API_KEY environment variable"}
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="stt-base-url">
                  Base URL {isCompatibleProvider ? "(Required)" : "(Optional)"}
                </Label>
                <Input
                  id="stt-base-url"
                  value={voiceConfig.stt.host || ""}
                  onChange={(e) => handleSTTChange({ host: e.target.value })}
                  placeholder="https://api.openai.com"
                />
                <p className="text-xs text-muted-foreground">
                  Leave empty to use the default OpenAI endpoint. For
                  self-hosted OpenAI-compatible services, provide either the
                  service root or its <code>/v1</code> base URL.
                </p>
              </div>
            </div>
          </div>

          {/* Command Intelligence Model */}
          <div className="space-y-4">
            <div className="flex items-center gap-2">
              <Settings className="h-4 w-4" />
              <Label className="text-base font-semibold">
                Command Intelligence
              </Label>
            </div>

            <div className="space-y-2">
              <Label htmlFor="intelligence-model">
                AI Model for Processing
              </Label>
              <Select
                value={voiceConfig.intelligence.model}
                onValueChange={(value) =>
                  handleIntelligenceChange({ model: value })
                }
              >
                <SelectTrigger id="intelligence-model">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {availableModels.length > 0 ? (
                    availableModels.map((model) => (
                      <SelectItem key={model} value={model}>
                        {model}
                      </SelectItem>
                    ))
                  ) : (
                    <SelectItem value="default">Default Model</SelectItem>
                  )}
                </SelectContent>
              </Select>
              <p className="text-xs text-muted-foreground">
                Model used to process transcriptions into commands and agent
                mentions
              </p>
            </div>
          </div>

          {/* Save Button */}
          <div className="flex justify-end">
            <Button onClick={handleSave} disabled={isLoading}>
              Save Voice Configuration
            </Button>
          </div>
        </CardContent>
      </Card>

      {/* Voice Features Card */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Info className="h-4 w-4" />
            Voice Features
          </CardTitle>
        </CardHeader>
        <CardContent>
          <ul className="space-y-2 text-sm">
            <li className="flex items-start gap-2">
              <span className="text-primary mt-0.5">🎤</span>
              <span>
                Automatic transcription of voice messages from all Matrix
                clients
              </span>
            </li>
            <li className="flex items-start gap-2">
              <span className="text-primary mt-0.5">🤖</span>
              <span>
                {
                  'Smart command recognition (e.g., "schedule a meeting" -> "!schedule meeting")'
                }
              </span>
            </li>
            <li className="flex items-start gap-2">
              <span className="text-primary mt-0.5">👥</span>
              <span>
                {'Agent name detection (e.g., "ask research" -> "@research")'}
              </span>
            </li>
            <li className="flex items-start gap-2">
              <span className="text-primary mt-0.5">🔒</span>
              <span>Support for both cloud and self-hosted STT services</span>
            </li>
            <li className="flex items-start gap-2">
              <span className="text-primary mt-0.5">🌍</span>
              <span>Multi-language support (depends on STT provider)</span>
            </li>
          </ul>
        </CardContent>
      </Card>
    </div>
  );
}
