

import { useState, useCallback, useMemo, Fragment } from 'react';
import type { LucideIcon } from 'lucide-react';
import {
  Image as ImageIcon,
  Video,
  Volume2,
  Mic,
  SlidersHorizontal,
  ChevronRight,
} from 'lucide-react';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectSeparator,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import { cn } from '@/lib/utils';
import { useI18n } from '@/lib/hooks/use-i18n';
import { useSettingsStore } from '@/lib/store/settings';
import { IMAGE_PROVIDERS } from '@/lib/media/image-providers';
import { VIDEO_PROVIDERS } from '@/lib/media/video-providers';
import { CUSTOM_ASR_DEFAULT_LANGUAGES } from '@/lib/audio/constants';
import { ASR_PROVIDERS, getASRSupportedLanguages } from '@/lib/audio/constants';
import type { ImageProviderId, VideoProviderId } from '@/lib/media/types';
import type { ASRProviderId } from '@/lib/audio/types';
import { isCustomASRProvider } from '@/lib/audio/types';
import type { SettingsSection } from '@/lib/types/settings';

interface MediaPopoverProps {
  onSettingsOpen: (section: SettingsSection) => void;
}

// ─── Provider icon maps ───
const IMAGE_PROVIDER_ICONS: Record<string, string> = {
  seedream: '/logos/doubao.svg',
  'openai-image': '/logos/openai.svg',
  'qwen-image': '/logos/bailian.svg',
  'nano-banana': '/logos/gemini.svg',
  'grok-image': '/logos/grok.svg',
};
const VIDEO_PROVIDER_ICONS: Record<string, string> = {
  seedance: '/logos/doubao.svg',
  kling: '/logos/kling.svg',
  veo: '/logos/gemini.svg',
  sora: '/logos/openai.svg',
  'grok-video': '/logos/grok.svg',
};

type TabId = 'image' | 'video' | 'tts' | 'asr';

const TABS: Array<{ id: TabId; icon: LucideIcon; label: string }> = [
  { id: 'image', icon: ImageIcon, label: 'Image' },
  { id: 'video', icon: Video, label: 'Video' },
  { id: 'tts', icon: Volume2, label: 'TTS' },
  { id: 'asr', icon: Mic, label: 'ASR' },
];

export function MediaPopover({ onSettingsOpen }: MediaPopoverProps) {
  const { t } = useI18n();
  const [open, setOpen] = useState(false);
  const [activeTab, setActiveTab] = useState<TabId>('image');

  // ─── Store ───
  const imageGenerationEnabled = useSettingsStore((s) => s.imageGenerationEnabled);
  const videoGenerationEnabled = useSettingsStore((s) => s.videoGenerationEnabled);
  const ttsEnabled = useSettingsStore((s) => s.ttsEnabled);
  const asrEnabled = useSettingsStore((s) => s.asrEnabled);
  const setImageGenerationEnabled = useSettingsStore((s) => s.setImageGenerationEnabled);
  const setVideoGenerationEnabled = useSettingsStore((s) => s.setVideoGenerationEnabled);
  const setTTSEnabled = useSettingsStore((s) => s.setTTSEnabled);
  const setASREnabled = useSettingsStore((s) => s.setASREnabled);

  const imageProviderId = useSettingsStore((s) => s.imageProviderId);
  const imageModelId = useSettingsStore((s) => s.imageModelId);
  const imageProvidersConfig = useSettingsStore((s) => s.imageProvidersConfig);
  const setImageProvider = useSettingsStore((s) => s.setImageProvider);
  const setImageModelId = useSettingsStore((s) => s.setImageModelId);

  const videoProviderId = useSettingsStore((s) => s.videoProviderId);
  const videoModelId = useSettingsStore((s) => s.videoModelId);
  const videoProvidersConfig = useSettingsStore((s) => s.videoProvidersConfig);
  const setVideoProvider = useSettingsStore((s) => s.setVideoProvider);
  const setVideoModelId = useSettingsStore((s) => s.setVideoModelId);

  const asrProviderId = useSettingsStore((s) => s.asrProviderId);
  const asrLanguage = useSettingsStore((s) => s.asrLanguage);
  const asrProvidersConfig = useSettingsStore((s) => s.asrProvidersConfig);
  const setASRProvider = useSettingsStore((s) => s.setASRProvider);
  const setASRLanguage = useSettingsStore((s) => s.setASRLanguage);

  const enabledMap: Record<TabId, boolean> = {
    image: imageGenerationEnabled,
    video: videoGenerationEnabled,
    tts: ttsEnabled,
    asr: asrEnabled,
  };

  const enabledCount = [
    imageGenerationEnabled,
    videoGenerationEnabled,
    ttsEnabled,
    asrEnabled,
  ].filter(Boolean).length;

  const cfgOk = useCallback(
    (
      configs: Record<string, { apiKey?: string; isServerConfigured?: boolean }>,
      id: string,
      needsKey: boolean,
    ) => !needsKey || !!configs[id]?.apiKey || !!configs[id]?.isServerConfigured,
    [],
  );

  // ─── Grouped select data (only available providers) ───
  const imageGroups = useMemo(
    () =>
      Object.values(IMAGE_PROVIDERS)
        .filter((p) => cfgOk(imageProvidersConfig, p.id, p.requiresApiKey))
        .map((p) => ({
          groupId: p.id,
          groupName: p.name,
          groupIcon: IMAGE_PROVIDER_ICONS[p.id],
          available: true,
          items: [...p.models, ...(imageProvidersConfig[p.id]?.customModels || [])].map((m) => ({
            id: m.id,
            name: m.name,
          })),
        })),
    [cfgOk, imageProvidersConfig],
  );

  const videoGroups = useMemo(
    () =>
      Object.values(VIDEO_PROVIDERS)
        .filter((p) => cfgOk(videoProvidersConfig, p.id, p.requiresApiKey))
        .map((p) => ({
          groupId: p.id,
          groupName: p.name,
          groupIcon: VIDEO_PROVIDER_ICONS[p.id],
          available: true,
          items: [...p.models, ...(videoProvidersConfig[p.id]?.customModels || [])].map((m) => ({
            id: m.id,
            name: m.name,
          })),
        })),
    [cfgOk, videoProvidersConfig],
  );

  // ASR: built-in + custom providers
  const asrGroups = useMemo(() => {
    const groups: SelectGroupData[] = [];

    // Built-in providers
    for (const p of Object.values(ASR_PROVIDERS)) {
      if (!cfgOk(asrProvidersConfig, p.id, p.requiresApiKey)) continue;
      groups.push({
        groupId: p.id,
        groupName: p.name,
        groupIcon: p.icon,
        available: true,
        items: getASRSupportedLanguages(p.id).map((l) => ({
          id: l,
          name: l,
        })),
      });
    }

    // Custom providers — only show if at least one model is configured
    for (const [id, cfg] of Object.entries(asrProvidersConfig)) {
      if (!isCustomASRProvider(id)) continue;
      const customModels = cfg.customModels || [];
      if (customModels.length === 0) continue;
      const providerName = cfg.customName || id;
      groups.push({
        groupId: id,
        groupName: providerName,
        available: true,
        items: CUSTOM_ASR_DEFAULT_LANGUAGES.map((l) => ({ id: l, name: l })),
      });
    }

    return groups;
  }, [asrProvidersConfig, cfgOk]);

  // Auto-select first enabled tab on open
  const handleOpenChange = (isOpen: boolean) => {
    setOpen(isOpen);
    if (isOpen) {
      const first = (['image', 'video', 'tts', 'asr'] as TabId[]).find((id) => enabledMap[id]);
      setActiveTab(first || 'image');
    }
  };

  return (
    <Popover open={open} onOpenChange={handleOpenChange}>
      <PopoverTrigger asChild>
        <button
          className={cn(
            'inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium transition-all cursor-pointer select-none whitespace-nowrap border',
            enabledCount > 0
              ? 'bg-violet-100 dark:bg-violet-900/30 text-violet-700 dark:text-violet-300 border-violet-200/60 dark:border-violet-700/50'
              : 'text-muted-foreground/70 hover:text-foreground hover:bg-muted/60 border-border/50',
          )}
        >
          <SlidersHorizontal className="size-3.5" />
          {imageGenerationEnabled && <ImageIcon className="size-3.5" />}
          {videoGenerationEnabled && <Video className="size-3.5" />}
          {ttsEnabled && <Volume2 className="size-3.5" />}
          {asrEnabled && <Mic className="size-3.5" />}
        </button>
      </PopoverTrigger>

      <PopoverContent align="start" side="bottom" avoidCollisions={false} className="w-80 p-0">
        {/* ── Tab bar (segmented control) ── */}
        <div className="p-2 pb-0">
          <div className="flex gap-0.5 p-0.5 bg-muted/60 rounded-lg">
            {TABS.map((tab) => {
              const isActive = activeTab === tab.id;
              const isEnabled = enabledMap[tab.id];
              const Icon = tab.icon;
              return (
                <button
                  key={tab.id}
                  onClick={() => setActiveTab(tab.id)}
                  className={cn(
                    'flex-1 flex items-center justify-center gap-1.5 py-1.5 rounded-md text-[11px] font-medium transition-all relative',
                    isActive
                      ? 'bg-background text-foreground shadow-sm'
                      : 'text-muted-foreground hover:text-foreground/80',
                  )}
                >
                  <Icon className="size-3.5" />
                  <span className="hidden sm:inline">{tab.label}</span>
                  {isEnabled && !isActive && (
                    <span className="absolute top-1 right-1 size-1.5 rounded-full bg-violet-500" />
                  )}
                </button>
              );
            })}
          </div>
        </div>

        {/* ── Tab content ── */}
        <div className="p-3 pt-2.5">
          {activeTab === 'image' && (
            <TabPanel
              icon={ImageIcon}
              label={t('media.imageCapability')}
              enabled={imageGenerationEnabled}
              onToggle={setImageGenerationEnabled}
            >
              <GroupedSelect
                groups={imageGroups}
                selectedGroupId={imageProviderId}
                selectedItemId={imageModelId}
                onSelect={(gid, iid) => {
                  setImageProvider(gid as ImageProviderId);
                  setImageModelId(iid);
                }}
              />
            </TabPanel>
          )}

          {activeTab === 'video' && (
            <TabPanel
              icon={Video}
              label={t('media.videoCapability')}
              enabled={videoGenerationEnabled}
              onToggle={setVideoGenerationEnabled}
            >
              <GroupedSelect
                groups={videoGroups}
                selectedGroupId={videoProviderId}
                selectedItemId={videoModelId}
                onSelect={(gid, iid) => {
                  setVideoProvider(gid as VideoProviderId);
                  setVideoModelId(iid);
                }}
              />
            </TabPanel>
          )}

          {activeTab === 'tts' && (
            <TabPanel
              icon={Volume2}
              label={t('media.ttsCapability')}
              enabled={ttsEnabled}
              onToggle={setTTSEnabled}
            />
          )}

          {activeTab === 'asr' && (
            <TabPanel
              icon={Mic}
              label={t('media.asrCapability')}
              enabled={asrEnabled}
              onToggle={setASREnabled}
            >
              <GroupedSelect
                groups={asrGroups}
                selectedGroupId={asrProviderId}
                selectedItemId={asrLanguage}
                onSelect={(gid, iid) => {
                  setASRProvider(gid as ASRProviderId);
                  setASRLanguage(iid);
                }}
              />
            </TabPanel>
          )}
        </div>

        {/* ── Footer ── */}
        <div className="border-t border-border/40">
          <button
            onClick={() => {
              setOpen(false);
              onSettingsOpen(activeTab);
            }}
            className="w-full flex items-center justify-between px-3.5 py-2.5 text-[11px] text-muted-foreground/60 hover:text-muted-foreground transition-colors"
          >
            <span>{t('toolbar.advancedSettings')}</span>
            <ChevronRight className="size-3" />
          </button>
        </div>
      </PopoverContent>
    </Popover>
  );
}

// ─── Tab panel: header (label + switch) + optional body ───
function TabPanel({
  icon: Icon,
  label,
  enabled,
  onToggle,
  children,
}: {
  icon: LucideIcon;
  label: string;
  enabled: boolean;
  onToggle: (v: boolean) => void;
  children?: React.ReactNode;
}) {
  return (
    <div className="space-y-2.5">
      <div className="flex items-center gap-2.5">
        <Icon
          className={cn(
            'size-4 shrink-0 transition-colors',
            enabled ? 'text-violet-600 dark:text-violet-400' : 'text-muted-foreground/50',
          )}
        />
        <span
          className={cn(
            'flex-1 text-sm font-medium transition-colors',
            !enabled && 'text-muted-foreground',
          )}
        >
          {label}
        </span>
        <Switch
          checked={enabled}
          onCheckedChange={onToggle}
          className="scale-[0.85] origin-right"
        />
      </div>
      {enabled && children}
    </div>
  );
}

// ─── Grouped provider+model select ───
interface SelectGroupData {
  groupId: string;
  groupName: string;
  groupIcon?: string;
  available: boolean;
  items: Array<{ id: string; name: string }>;
}

function GroupedSelect({
  groups,
  selectedGroupId,
  selectedItemId,
  onSelect,
}: {
  groups: SelectGroupData[];
  selectedGroupId: string;
  selectedItemId: string;
  onSelect: (groupId: string, itemId: string) => void;
}) {
  const composite = `${selectedGroupId}::${selectedItemId}`;
  // When multiple groups share the same groupId (e.g. browser-native-tts split by language),
  // find the sub-group that actually contains the selected item.
  const selectedGroup =
    groups.find(
      (g) => g.groupId === selectedGroupId && g.items.some((item) => item.id === selectedItemId),
    ) || groups.find((g) => g.groupId === selectedGroupId);

  return (
    <Select
      value={composite}
      onValueChange={(v) => {
        const sep = v.indexOf('::');
        if (sep === -1) return;
        onSelect(v.slice(0, sep), v.slice(sep + 2));
      }}
    >
      <SelectTrigger className="h-8 w-full rounded-lg border-border/40 bg-background/80 hover:bg-muted/40 shadow-none text-xs focus:ring-1 focus:ring-ring/30 px-2.5">
        <span className="flex items-center gap-2 min-w-0 flex-1 overflow-hidden">
          {selectedGroup?.groupIcon && (
            <img src={selectedGroup.groupIcon} alt="" className="size-4 rounded-sm shrink-0" />
          )}
          <span className="font-medium truncate">{selectedGroup?.groupName}</span>
          <span className="text-muted-foreground/40">/</span>
          <span className="text-muted-foreground truncate">
            <SelectValue />
          </span>
        </span>
      </SelectTrigger>
      <SelectContent>
        {groups.map((group, i) => (
          <Fragment key={`${group.groupId}-${i}`}>
            {i > 0 && <SelectSeparator />}
            <SelectGroup>
              <SelectLabel className="flex items-center gap-1.5 text-[10px] font-semibold uppercase tracking-wider">
                {group.groupIcon && (
                  <img
                    src={group.groupIcon}
                    alt=""
                    className={cn('size-3.5 rounded-sm', !group.available && 'opacity-40')}
                  />
                )}
                {group.groupName}
              </SelectLabel>
              {group.items.map((item) => (
                <SelectItem
                  key={`${group.groupId}::${item.id}`}
                  value={`${group.groupId}::${item.id}`}
                  disabled={!group.available}
                  className="text-xs"
                >
                  {item.name}
                </SelectItem>
              ))}
            </SelectGroup>
          </Fragment>
        ))}
      </SelectContent>
    </Select>
  );
}
