import type { AutoUpdateConfig } from '../types'
import type { PluginDeclaration, PluginDetail } from '@/app/components/plugins/types'
import { QueryClientProvider } from '@tanstack/react-query'
import { fireEvent, render as rtlRender, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import dayjs from 'dayjs'
import timezone from 'dayjs/plugin/timezone'
import utc from 'dayjs/plugin/utc'
import * as React from 'react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
import { createAccountProfileQueryClient } from '@/test/console/account-profile'
import { PluginCategoryEnum, PluginSource } from '../../../types'
import AutoUpdateSetting from '../index'
import NoDataPlaceholder from '../no-data-placeholder'
import NoPluginSelected from '../no-plugin-selected'
import PluginsPicker from '../plugins-picker'
import PluginsSelected from '../plugins-selected'
import StrategyPicker from '../strategy-picker'
import ToolItem from '../tool-item'
import ToolPicker from '../tool-picker'
import { AUTO_UPDATE_MODE, AUTO_UPDATE_STRATEGY } from '../types'
import {
  convertLocalSecondsToUTCDaySeconds,
  convertUTCDaySecondsToLocalSeconds,
  dayjsToTimeOfDay,
  timeOfDayToDayjs,
} from '../utils'

// Setup dayjs plugins
dayjs.extend(utc)
dayjs.extend(timezone)

// Mock app context
const mockTimezone = 'America/New_York'

// Mock modal context
const mockSetShowAccountSettingModal = vi.fn()
vi.mock('@/context/modal-context', () => ({
  useModalContextSelector: (
    selector: (s: {
      setShowAccountSettingModal: typeof mockSetShowAccountSettingModal
    }) => typeof mockSetShowAccountSettingModal,
  ) => {
    return selector({ setShowAccountSettingModal: mockSetShowAccountSettingModal })
  },
}))

// Mock i18n context

vi.mock('react-i18next', async () => {
  const { withSelectorKey, withSelectorKeyProps } = await import('@/test/i18n-mock')
  return {
    useTranslation: (defaultNs?: string) => ({
      t: withSelectorKey((key: string, options?: Record<string, unknown>) => {
        const ns = (options?.ns as string | undefined) ?? defaultNs
        const params = { ...options }
        delete params.ns
        const suffix = Object.keys(params).length > 0 ? `:${JSON.stringify(params)}` : ''
        return `${ns ? `${ns}.` : ''}${key}${suffix}`
      }),
      i18n: {
        language: 'en',
        changeLanguage: vi.fn(),
      },
    }),
    Trans: withSelectorKeyProps(
      ({
        i18nKey,
        components,
      }: {
        i18nKey: string
        components?: Record<string, React.ReactElement>
      }) => {
        const setTimezone = components?.setTimezone
        if (setTimezone)
          return React.createElement(
            setTimezone.type as React.ElementType,
            setTimezone.props,
            i18nKey,
          )

        return <span>{i18nKey}</span>
      },
    ),
  }
})

// Mock plugins service
const mockPluginsData: { plugins: PluginDetail[] } = { plugins: [] }
vi.mock('@/service/use-plugins', () => ({
  useInstalledPluginList: () => ({
    data: mockPluginsData,
    isLoading: false,
  }),
}))

// Mock popover component for ToolPicker and StrategyPicker
let mockPopoverOpen = false
let forcePopoverContentVisible = false // Allow tests to force content visibility
let mockPopoverOnOpenChange: ((open: boolean) => void) | undefined
vi.mock('@langgenius/dify-ui/popover', () => ({
  Popover: ({
    children,
    open = false,
    onOpenChange,
  }: {
    children: React.ReactNode
    open?: boolean
    onOpenChange?: (open: boolean) => void
  }) => {
    mockPopoverOpen = open
    mockPopoverOnOpenChange = onOpenChange
    return (
      <div data-testid="popover" data-open={open}>
        {children}
      </div>
    )
  },
  PopoverTrigger: ({
    children,
    render,
    onClick,
    className,
  }: {
    children?: React.ReactNode
    render?: React.ReactNode
    onClick?: (e: React.MouseEvent) => void
    className?: string
  }) => (
    <div
      data-testid="popover-trigger"
      role="button"
      aria-label="popover trigger"
      tabIndex={0}
      onClick={(e) => {
        onClick?.(e)
        if (!onClick) mockPopoverOnOpenChange?.(!mockPopoverOpen)
      }}
      onKeyDown={(e) => {
        if ((e.key === 'Enter' || e.key === ' ') && !onClick)
          mockPopoverOnOpenChange?.(!mockPopoverOpen)
      }}
      className={className}
    >
      {render ?? children}
    </div>
  ),
  PopoverContent: ({
    children,
    className,
    popupClassName,
  }: {
    children: React.ReactNode
    className?: string
    popupClassName?: string
  }) => {
    if (!mockPopoverOpen && !forcePopoverContentVisible) return null
    return (
      <div
        data-testid="popover-content"
        className={[className, popupClassName].filter(Boolean).join(' ')}
      >
        {children}
      </div>
    )
  },
}))

// Mock TimePicker component - simplified stateless mock
vi.mock('@/app/components/base/date-and-time-picker/time-picker', () => ({
  default: ({
    value,
    onChange,
    onClear,
    renderTrigger,
  }: {
    value: { format: (f: string) => string }
    onChange: (v: unknown) => void
    onClear: () => void
    title?: string
    renderTrigger: (params: {
      inputElem: React.ReactNode
      onClick: () => void
      isOpen: boolean
    }) => React.ReactNode
  }) => {
    const inputElem = <span data-testid="time-input">{value.format('HH:mm')}</span>

    return (
      <div data-testid="time-picker">
        {renderTrigger({
          inputElem,
          onClick: () => {},
          isOpen: false,
        })}
        <div data-testid="time-picker-dropdown">
          <button
            data-testid="time-picker-set"
            onClick={() => {
              onChange(dayjs().hour(10).minute(30))
            }}
          >
            Set 10:30
          </button>
          <button
            data-testid="time-picker-clear"
            onClick={() => {
              onClear()
            }}
          >
            Clear
          </button>
        </div>
      </div>
    )
  },
}))

// Mock utils from date-and-time-picker
vi.mock('@/app/components/base/date-and-time-picker/utils/dayjs', () => ({
  convertTimezoneToOffsetStr: (tz: string) => {
    if (tz === 'America/New_York') return 'GMT-5'
    if (tz === 'Asia/Shanghai') return 'GMT+8'
    return 'GMT+0'
  },
}))

// Mock SearchBox component
vi.mock('@/app/components/plugins/marketplace/search-box', () => ({
  default: ({
    search,
    onSearchChange,
    tags: _tags,
    onTagsChange: _onTagsChange,
    placeholder,
  }: {
    search: string
    onSearchChange: (v: string) => void
    tags: string[]
    onTagsChange: (v: string[]) => void
    placeholder: string
  }) => (
    <div data-testid="search-box">
      <input
        data-testid="search-input"
        value={search}
        onChange={(e) => onSearchChange(e.target.value)}
        placeholder={placeholder}
      />
    </div>
  ),
}))

// Mock Icon component
vi.mock('@/app/components/plugins/card/base/card-icon', () => ({
  default: ({ size, src }: { size: string; src: string }) => (
    <img data-testid="plugin-icon" data-size={size} src={src} alt="plugin icon" />
  ),
}))

// Mock icons
vi.mock('@/app/components/base/icons/src/vender/line/general', () => ({
  SearchMenu: ({ className }: { className?: string }) => (
    <span data-testid="search-menu-icon" className={className}>
      🔍
    </span>
  ),
}))

vi.mock('@/app/components/base/icons/src/vender/other', () => ({
  Group: ({ className }: { className?: string }) => (
    <span data-testid="group-icon" className={className}>
      📦
    </span>
  ),
}))

// Mock PLUGIN_TYPE_SEARCH_MAP
vi.mock('../../../marketplace/constants', () => ({
  PLUGIN_TYPE_SEARCH_MAP: {
    all: 'all',
    model: 'model',
    tool: 'tool',
    agent: 'agent',
    extension: 'extension',
    datasource: 'datasource',
    trigger: 'trigger',
    bundle: 'bundle',
  },
}))

// Mock i18n renderI18nObject
vi.mock('@/i18n-config', () => ({
  renderI18nObject: (obj: Record<string, string>, lang: string) => obj[lang] || obj['en-US'] || '',
}))

// ================================
// Test Data Factories
// ================================

const createMockPluginDeclaration = (
  overrides: Partial<PluginDeclaration> = {},
): PluginDeclaration => ({
  plugin_unique_identifier: 'test-plugin-id',
  version: '1.0.0',
  author: 'test-author',
  icon: 'test-icon.png',
  name: 'Test Plugin',
  category: PluginCategoryEnum.tool,
  label: { 'en-US': 'Test Plugin' } as PluginDeclaration['label'],
  description: { 'en-US': 'A test plugin' } as PluginDeclaration['description'],
  created_at: '2024-01-01',
  resource: {},
  plugins: {},
  verified: true,
  endpoint: { settings: [], endpoints: [] },
  model: {},
  tags: ['tag1', 'tag2'],
  agent_strategy: {},
  meta: { version: '1.0.0' },
  trigger: {
    events: [],
    identity: {
      author: 'test',
      name: 'test',
      label: { 'en-US': 'Test' } as PluginDeclaration['label'],
      description: { 'en-US': 'Test' } as PluginDeclaration['description'],
      icon: 'test.png',
      tags: [],
    },
    subscription_constructor: {
      credentials_schema: [],
      oauth_schema: { client_schema: [], credentials_schema: [] },
      parameters: [],
    },
    subscription_schema: [],
  },
  ...overrides,
})

const createMockPluginDetail = (overrides: Partial<PluginDetail> = {}): PluginDetail => ({
  id: 'plugin-1',
  created_at: '2024-01-01',
  updated_at: '2024-01-01',
  name: 'test-plugin',
  plugin_id: 'test-plugin-id',
  plugin_unique_identifier: 'test-plugin-unique',
  declaration: createMockPluginDeclaration(),
  installation_id: 'install-1',
  tenant_id: 'tenant-1',
  endpoints_setups: 0,
  endpoints_active: 0,
  version: '1.0.0',
  latest_version: '1.1.0',
  latest_unique_identifier: 'test-plugin-latest',
  source: PluginSource.marketplace,
  status: 'active',
  deprecated_reason: '',
  alternative_plugin_id: '',
  ...overrides,
})

const createMockAutoUpdateConfig = (
  overrides: Partial<AutoUpdateConfig> = {},
): AutoUpdateConfig => ({
  strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
  upgrade_time_of_day: 36000, // 10:00 UTC
  upgrade_mode: AUTO_UPDATE_MODE.update_all,
  exclude_plugins: [],
  include_plugins: [],
  ...overrides,
})

// ================================
// Helper Functions
// ================================

const createQueryClient = () => createAccountProfileQueryClient({ timezone: mockTimezone })

const render = (ui: React.ReactElement) => {
  const queryClient = createQueryClient()
  const Wrapper = ({ children }: { children: React.ReactNode }) => (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  )
  return rtlRender(ui, { wrapper: Wrapper })
}

const renderWithQueryClient = (ui: React.ReactElement) => {
  const queryClient = createQueryClient()
  const Wrapper = ({ children }: { children: React.ReactNode }) => (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  )
  return rtlRender(ui, { wrapper: Wrapper })
}

// ================================
// Test Suites
// ================================

describe('auto-update-setting', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    mockPopoverOpen = false
    mockPopoverOnOpenChange = undefined
    forcePopoverContentVisible = false
    mockPluginsData.plugins = []
  })

  // ============================================================
  // Types and Config Tests
  // ============================================================
  describe('types.ts', () => {
    describe('AUTO_UPDATE_STRATEGY enum', () => {
      it('should have correct values', () => {
        expect(AUTO_UPDATE_STRATEGY.fixOnly).toBe('fix_only')
        expect(AUTO_UPDATE_STRATEGY.disabled).toBe('disabled')
        expect(AUTO_UPDATE_STRATEGY.latest).toBe('latest')
      })

      it('should contain exactly 3 strategies', () => {
        const values = Object.values(AUTO_UPDATE_STRATEGY)
        expect(values).toHaveLength(3)
      })
    })

    describe('AUTO_UPDATE_MODE enum', () => {
      it('should have correct values', () => {
        expect(AUTO_UPDATE_MODE.partial).toBe('partial')
        expect(AUTO_UPDATE_MODE.exclude).toBe('exclude')
        expect(AUTO_UPDATE_MODE.update_all).toBe('all')
      })

      it('should contain exactly 3 modes', () => {
        const values = Object.values(AUTO_UPDATE_MODE)
        expect(values).toHaveLength(3)
      })
    })
  })

  // ============================================================
  // Utils Tests (Extended coverage beyond utils.spec.ts)
  // ============================================================
  describe('utils.ts', () => {
    describe('timeOfDayToDayjs', () => {
      it('should convert 0 seconds to midnight', () => {
        const result = timeOfDayToDayjs(0)
        expect(result.hour()).toBe(0)
        expect(result.minute()).toBe(0)
      })

      it('should convert 3600 seconds to 1:00', () => {
        const result = timeOfDayToDayjs(3600)
        expect(result.hour()).toBe(1)
        expect(result.minute()).toBe(0)
      })

      it('should convert 36000 seconds to 10:00', () => {
        const result = timeOfDayToDayjs(36000)
        expect(result.hour()).toBe(10)
        expect(result.minute()).toBe(0)
      })

      it('should convert 43200 seconds to 12:00 (noon)', () => {
        const result = timeOfDayToDayjs(43200)
        expect(result.hour()).toBe(12)
        expect(result.minute()).toBe(0)
      })

      it('should convert 82800 seconds to 23:00', () => {
        const result = timeOfDayToDayjs(82800)
        expect(result.hour()).toBe(23)
        expect(result.minute()).toBe(0)
      })

      it('should handle minutes correctly', () => {
        const result = timeOfDayToDayjs(5400) // 1:30
        expect(result.hour()).toBe(1)
        expect(result.minute()).toBe(30)
      })

      it('should handle 15 minute intervals', () => {
        expect(timeOfDayToDayjs(900).minute()).toBe(15)
        expect(timeOfDayToDayjs(1800).minute()).toBe(30)
        expect(timeOfDayToDayjs(2700).minute()).toBe(45)
      })
    })

    describe('dayjsToTimeOfDay', () => {
      it('should return 0 for undefined input', () => {
        expect(dayjsToTimeOfDay(undefined)).toBe(0)
      })

      it('should convert midnight to 0', () => {
        const midnight = dayjs().hour(0).minute(0)
        expect(dayjsToTimeOfDay(midnight)).toBe(0)
      })

      it('should convert 1:00 to 3600', () => {
        const time = dayjs().hour(1).minute(0)
        expect(dayjsToTimeOfDay(time)).toBe(3600)
      })

      it('should convert 10:30 to 37800', () => {
        const time = dayjs().hour(10).minute(30)
        expect(dayjsToTimeOfDay(time)).toBe(37800)
      })

      it('should convert 23:59 to 86340', () => {
        const time = dayjs().hour(23).minute(59)
        expect(dayjsToTimeOfDay(time)).toBe(86340)
      })
    })

    describe('convertLocalSecondsToUTCDaySeconds', () => {
      it('should convert local midnight to UTC for positive offset timezone', () => {
        // Shanghai is UTC+8, local midnight should be 16:00 UTC previous day
        const result = convertLocalSecondsToUTCDaySeconds(0, 'Asia/Shanghai')
        expect(result).toBe((24 - 8) * 3600)
      })

      it('should handle negative offset timezone', () => {
        // New York is UTC-5 (or -4 during DST), local midnight should be 5:00 UTC
        const result = convertLocalSecondsToUTCDaySeconds(0, 'America/New_York')
        // Result depends on DST, but should be in valid range
        expect(result).toBeGreaterThanOrEqual(0)
        expect(result).toBeLessThan(86400)
      })

      it('should be reversible with convertUTCDaySecondsToLocalSeconds', () => {
        const localSeconds = 36000 // 10:00 local
        const utcSeconds = convertLocalSecondsToUTCDaySeconds(localSeconds, 'Asia/Shanghai')
        const backToLocal = convertUTCDaySecondsToLocalSeconds(utcSeconds, 'Asia/Shanghai')
        expect(backToLocal).toBe(localSeconds)
      })
    })

    describe('convertUTCDaySecondsToLocalSeconds', () => {
      it('should convert UTC midnight to local time for positive offset timezone', () => {
        // UTC midnight in Shanghai (UTC+8) is 8:00 local
        const result = convertUTCDaySecondsToLocalSeconds(0, 'Asia/Shanghai')
        expect(result).toBe(8 * 3600)
      })

      it('should handle edge cases near day boundaries', () => {
        // UTC 23:00 in Shanghai is 7:00 next day
        const result = convertUTCDaySecondsToLocalSeconds(23 * 3600, 'Asia/Shanghai')
        expect(result).toBeGreaterThanOrEqual(0)
        expect(result).toBeLessThan(86400)
      })
    })
  })

  // ============================================================
  // NoDataPlaceholder Component Tests
  // ============================================================
  describe('NoDataPlaceholder (no-data-placeholder.tsx)', () => {
    describe('Rendering', () => {
      it('should render with noPlugins=true showing group icon', () => {
        // Act
        render(<NoDataPlaceholder className="test-class" noPlugins={true} />)

        // Assert
        expect(screen.getByTestId('group-icon')).toBeInTheDocument()
        expect(
          screen.getByText('plugin.autoUpdate.noPluginPlaceholder.noInstalled'),
        ).toBeInTheDocument()
      })

      it('should render with noPlugins=false showing search icon', () => {
        // Act
        render(<NoDataPlaceholder className="test-class" noPlugins={false} />)

        // Assert
        expect(screen.getByTestId('search-menu-icon')).toBeInTheDocument()
        expect(
          screen.getByText('plugin.autoUpdate.noPluginPlaceholder.noFound'),
        ).toBeInTheDocument()
      })

      it('should render with noPlugins=undefined (default) showing search icon', () => {
        // Act
        render(<NoDataPlaceholder className="test-class" />)

        // Assert
        expect(screen.getByTestId('search-menu-icon')).toBeInTheDocument()
      })
    })
  })

  describe('NoPluginSelected (no-plugin-selected.tsx)', () => {
    describe('Rendering', () => {
      it('should render partial mode placeholder', () => {
        // Act
        render(<NoPluginSelected updateMode={AUTO_UPDATE_MODE.partial} />)

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.upgradeModePlaceholder.partial'),
        ).toBeInTheDocument()
      })

      it('should render exclude mode placeholder', () => {
        // Act
        render(<NoPluginSelected updateMode={AUTO_UPDATE_MODE.exclude} />)

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.upgradeModePlaceholder.exclude'),
        ).toBeInTheDocument()
      })
    })
  })

  describe('PluginsSelected (plugins-selected.tsx)', () => {
    describe('Rendering', () => {
      it('should render empty when no plugins', () => {
        // Act
        const { container } = render(<PluginsSelected plugins={[]} />)

        // Assert
        expect(container.querySelectorAll('[data-testid="plugin-icon"]')).toHaveLength(0)
      })

      it('should render all plugins when count is below MAX_DISPLAY_COUNT (14)', () => {
        // Arrange
        const plugins = Array.from({ length: 10 }, (_, i) => `plugin-${i}`)

        // Act
        render(<PluginsSelected plugins={plugins} />)

        // Assert
        const icons = screen.getAllByTestId('plugin-icon')
        expect(icons).toHaveLength(10)
      })

      it('should render MAX_DISPLAY_COUNT plugins with overflow indicator when count exceeds limit', () => {
        // Arrange
        const plugins = Array.from({ length: 20 }, (_, i) => `plugin-${i}`)

        // Act
        render(<PluginsSelected plugins={plugins} />)

        // Assert
        const icons = screen.getAllByTestId('plugin-icon')
        expect(icons).toHaveLength(14)
        expect(screen.getByText('+6')).toBeInTheDocument()
      })

      it('should render correct icon URLs', () => {
        // Arrange
        const plugins = ['plugin-a', 'plugin-b']

        // Act
        render(<PluginsSelected plugins={plugins} />)

        // Assert
        const icons = screen.getAllByTestId('plugin-icon')
        expect(icons[0]).toHaveAttribute('src', expect.stringContaining('plugin-a'))
        expect(icons[1]).toHaveAttribute('src', expect.stringContaining('plugin-b'))
      })
    })

    describe('Edge Cases', () => {
      it('should handle exactly MAX_DISPLAY_COUNT plugins without overflow', () => {
        // Arrange - exactly 14 plugins (MAX_DISPLAY_COUNT)
        const plugins = Array.from({ length: 14 }, (_, i) => `plugin-${i}`)

        // Act
        render(<PluginsSelected plugins={plugins} />)

        // Assert - all 14 icons are displayed
        expect(screen.getAllByTestId('plugin-icon')).toHaveLength(14)
        expect(screen.queryByText('+0')).not.toBeInTheDocument()
      })

      it('should handle MAX_DISPLAY_COUNT + 1 plugins showing overflow', () => {
        // Arrange - 15 plugins
        const plugins = Array.from({ length: 15 }, (_, i) => `plugin-${i}`)

        // Act
        render(<PluginsSelected plugins={plugins} />)

        // Assert
        expect(screen.getAllByTestId('plugin-icon')).toHaveLength(14)
        expect(screen.getByText('+1')).toBeInTheDocument()
      })
    })
  })

  describe('ToolItem (tool-item.tsx)', () => {
    const defaultProps = {
      payload: createMockPluginDetail(),
      isChecked: false,
      onCheckChange: vi.fn(),
    }

    describe('Rendering', () => {
      it('should render plugin icon', () => {
        // Act
        render(<ToolItem {...defaultProps} />)

        // Assert
        expect(screen.getByTestId('plugin-icon')).toBeInTheDocument()
      })

      it('should render plugin label', () => {
        // Arrange
        const props = {
          ...defaultProps,
          payload: createMockPluginDetail({
            declaration: createMockPluginDeclaration({
              label: { 'en-US': 'My Test Plugin' } as PluginDeclaration['label'],
            }),
          }),
        }

        // Act
        render(<ToolItem {...props} />)

        // Assert
        expect(screen.getByText('My Test Plugin')).toBeInTheDocument()
      })

      it('should render plugin author', () => {
        // Arrange
        const props = {
          ...defaultProps,
          payload: createMockPluginDetail({
            declaration: createMockPluginDeclaration({
              author: 'Plugin Author',
            }),
          }),
        }

        // Act
        render(<ToolItem {...props} />)

        // Assert
        expect(screen.getByText('Plugin Author')).toBeInTheDocument()
      })

      it('should render checkbox unchecked when isChecked is false', () => {
        // Act
        render(<ToolItem {...defaultProps} isChecked={false} />)

        // Assert
        expect(screen.getByRole('checkbox')).not.toBeChecked()
      })

      it('should render checkbox checked when isChecked is true', () => {
        // Act
        render(<ToolItem {...defaultProps} isChecked={true} />)

        // Assert
        expect(screen.getByRole('checkbox')).toBeChecked()
      })
    })

    describe('User Interactions', () => {
      it('should call onCheckChange when checkbox is clicked', () => {
        // Arrange
        const onCheckChange = vi.fn()

        // Act
        render(<ToolItem {...defaultProps} onCheckChange={onCheckChange} />)
        fireEvent.click(screen.getByRole('checkbox'))

        // Assert
        expect(onCheckChange).toHaveBeenCalledTimes(1)
      })
    })
  })

  describe('StrategyPicker (strategy-picker.tsx)', () => {
    const i18nKeyByStrategy: Record<AUTO_UPDATE_STRATEGY, 'disabled' | 'fixOnly' | 'latest'> = {
      [AUTO_UPDATE_STRATEGY.disabled]: 'disabled',
      [AUTO_UPDATE_STRATEGY.fixOnly]: 'fixOnly',
      [AUTO_UPDATE_STRATEGY.latest]: 'latest',
    }

    const triggerName = (strategy: AUTO_UPDATE_STRATEGY) =>
      new RegExp(`plugin\\.autoUpdate\\.strategy\\.${i18nKeyByStrategy[strategy]}\\.name`, 'i')

    const findOption = (key: 'disabled' | 'fixOnly' | 'latest') => {
      const options = screen.getAllByRole('button')
      const option = options.find((item) =>
        item.textContent?.includes(`plugin.autoUpdate.strategy.${key}.name`),
      )
      if (!option) throw new Error(`Strategy option "${key}" not found`)
      return option
    }

    describe('Rendering', () => {
      it('should render the segmented control with all strategies', () => {
        render(<StrategyPicker value={AUTO_UPDATE_STRATEGY.disabled} onChange={vi.fn()} />)

        expect(
          screen.getByRole('group', { name: 'plugin.autoUpdate.automaticUpdates' }),
        ).toBeInTheDocument()
        expect(
          screen.getByRole('button', { name: triggerName(AUTO_UPDATE_STRATEGY.disabled) }),
        ).toBeInTheDocument()
        const options = screen.getAllByRole('button')
        expect(options).toHaveLength(3)
        expect(
          options.some((o) => o.textContent?.includes('plugin.autoUpdate.strategy.disabled.name')),
        ).toBe(true)
        expect(
          options.some((o) => o.textContent?.includes('plugin.autoUpdate.strategy.fixOnly.name')),
        ).toBe(true)
        expect(
          options.some((o) => o.textContent?.includes('plugin.autoUpdate.strategy.latest.name')),
        ).toBe(true)
      })
    })

    describe('User Interactions', () => {
      it.each<[AUTO_UPDATE_STRATEGY, 'disabled' | 'fixOnly' | 'latest', AUTO_UPDATE_STRATEGY]>([
        [AUTO_UPDATE_STRATEGY.disabled, 'fixOnly', AUTO_UPDATE_STRATEGY.fixOnly],
        [AUTO_UPDATE_STRATEGY.disabled, 'latest', AUTO_UPDATE_STRATEGY.latest],
        [AUTO_UPDATE_STRATEGY.fixOnly, 'disabled', AUTO_UPDATE_STRATEGY.disabled],
      ])(
        'should call onChange with %s -> %s when option is selected',
        async (initial, optionKey, expected) => {
          const user = userEvent.setup()
          const onChange = vi.fn()
          render(<StrategyPicker value={initial} onChange={onChange} />)

          await user.click(findOption(optionKey))

          expect(onChange).toHaveBeenCalledWith(expected)
        },
      )

      it('should mark only the currently selected option with aria-pressed', () => {
        render(<StrategyPicker value={AUTO_UPDATE_STRATEGY.fixOnly} onChange={vi.fn()} />)

        const options = screen.getAllByRole('button')
        const checked = options.filter((o) => o.getAttribute('aria-pressed') === 'true')

        expect(checked).toHaveLength(1)
        expect(checked[0]).toHaveTextContent('plugin.autoUpdate.strategy.fixOnly.name')
      })
    })
  })

  describe('ToolPicker (tool-picker.tsx)', () => {
    const defaultProps = {
      trigger: <button>Select Plugins</button>,
      value: [] as string[],
      onChange: vi.fn(),
      isShow: false,
      onShowChange: vi.fn(),
    }

    describe('Rendering', () => {
      it('should render trigger element', () => {
        // Act
        render(<ToolPicker {...defaultProps} />)

        // Assert
        expect(screen.getByRole('button', { name: 'Select Plugins' })).toBeInTheDocument()
      })

      it('should not render content when isShow is false', () => {
        // Act
        render(<ToolPicker {...defaultProps} isShow={false} />)

        // Assert
        expect(screen.queryByTestId('popover-content')).not.toBeInTheDocument()
      })

      it('should render search box and tabs when isShow is true', () => {
        // Arrange
        mockPopoverOpen = true

        // Act
        render(<ToolPicker {...defaultProps} isShow={true} />)

        // Assert
        expect(screen.getByTestId('search-box')).toBeInTheDocument()
      })

      it('should show NoDataPlaceholder when no plugins and no search query', () => {
        // Arrange
        mockPopoverOpen = true
        mockPluginsData.plugins = []

        // Act
        renderWithQueryClient(<ToolPicker {...defaultProps} isShow={true} />)

        // Assert - should show "No plugins installed" when no query
        expect(screen.getByTestId('group-icon')).toBeInTheDocument()
      })
    })

    describe('Filtering', () => {
      beforeEach(() => {
        mockPluginsData.plugins = [
          createMockPluginDetail({
            plugin_id: 'tool-plugin',
            source: PluginSource.marketplace,
            declaration: createMockPluginDeclaration({
              category: PluginCategoryEnum.tool,
              label: { 'en-US': 'Tool Plugin' } as PluginDeclaration['label'],
            }),
          }),
          createMockPluginDetail({
            plugin_id: 'model-plugin',
            source: PluginSource.marketplace,
            declaration: createMockPluginDeclaration({
              category: PluginCategoryEnum.model,
              label: { 'en-US': 'Model Plugin' } as PluginDeclaration['label'],
            }),
          }),
          createMockPluginDetail({
            plugin_id: 'github-plugin',
            source: PluginSource.github,
            declaration: createMockPluginDeclaration({
              label: { 'en-US': 'GitHub Plugin' } as PluginDeclaration['label'],
            }),
          }),
        ]
      })

      it('should filter out non-marketplace plugins', () => {
        // Arrange
        mockPopoverOpen = true

        // Act
        renderWithQueryClient(<ToolPicker {...defaultProps} isShow={true} />)

        // Assert - GitHub plugin should not be shown
        expect(screen.queryByText('GitHub Plugin')).not.toBeInTheDocument()
      })

      it('should filter by search query', () => {
        // Arrange
        mockPopoverOpen = true

        // Act
        renderWithQueryClient(<ToolPicker {...defaultProps} isShow={true} />)

        // Type in search box
        fireEvent.change(screen.getByTestId('search-input'), { target: { value: 'tool' } })

        // Assert - only tool plugin should match
        expect(screen.getByText('Tool Plugin')).toBeInTheDocument()
        expect(screen.queryByText('Model Plugin')).not.toBeInTheDocument()
      })
    })

    describe('User Interactions', () => {
      it('should call onShowChange when trigger is clicked', () => {
        // Arrange
        const onShowChange = vi.fn()

        // Act
        render(<ToolPicker {...defaultProps} onShowChange={onShowChange} />)
        fireEvent.click(screen.getByTestId('popover-trigger'))

        // Assert
        expect(onShowChange).toHaveBeenCalledWith(true)
      })

      it('should call onChange when plugin is selected', () => {
        // Arrange
        mockPopoverOpen = true
        mockPluginsData.plugins = [
          createMockPluginDetail({
            plugin_id: 'test-plugin',
            source: PluginSource.marketplace,
            declaration: createMockPluginDeclaration({
              label: { 'en-US': 'Test Plugin' } as PluginDeclaration['label'],
            }),
          }),
        ]
        const onChange = vi.fn()

        // Act
        renderWithQueryClient(<ToolPicker {...defaultProps} isShow={true} onChange={onChange} />)
        fireEvent.click(screen.getByRole('checkbox'))

        // Assert
        expect(onChange).toHaveBeenCalledWith(['test-plugin'])
      })

      it('should unselect plugin when already selected', () => {
        // Arrange
        mockPopoverOpen = true
        mockPluginsData.plugins = [
          createMockPluginDetail({
            plugin_id: 'test-plugin',
            source: PluginSource.marketplace,
          }),
        ]
        const onChange = vi.fn()

        // Act
        renderWithQueryClient(
          <ToolPicker
            {...defaultProps}
            isShow={true}
            value={['test-plugin']}
            onChange={onChange}
          />,
        )
        fireEvent.click(screen.getByRole('checkbox'))

        // Assert
        expect(onChange).toHaveBeenCalledWith([])
      })
    })
  })

  // ============================================================
  // PluginsPicker Component Tests
  // ============================================================
  describe('PluginsPicker (plugins-picker.tsx)', () => {
    const defaultProps = {
      updateMode: AUTO_UPDATE_MODE.partial,
      value: [] as string[],
      onChange: vi.fn(),
    }

    describe('Rendering', () => {
      it('should render NoPluginSelected when no plugins selected', () => {
        // Act
        render(<PluginsPicker {...defaultProps} />)

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.upgradeModePlaceholder.partial'),
        ).toBeInTheDocument()
      })

      it('should render selected plugins count and clear button when plugins selected', () => {
        // Act
        render(<PluginsPicker {...defaultProps} value={['plugin-1', 'plugin-2']} />)

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.partialUPdate:{"count":2,"num":2}'),
        ).toBeInTheDocument()
        expect(
          screen.getByRole('button', { name: 'plugin.autoUpdate.operation.clearAll' }),
        ).toBeInTheDocument()
      })

      it('should render select button', () => {
        // Act
        render(<PluginsPicker {...defaultProps} />)

        // Assert
        expect(screen.getByText('plugin.autoUpdate.operation.select')).toBeInTheDocument()
      })

      it('should show exclude mode text when in exclude mode', () => {
        // Act
        render(
          <PluginsPicker
            {...defaultProps}
            updateMode={AUTO_UPDATE_MODE.exclude}
            value={['plugin-1']}
          />,
        )

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.excludeUpdate:{"count":1,"num":1}'),
        ).toBeInTheDocument()
      })
    })

    describe('User Interactions', () => {
      it('should call onChange with empty array when clear is clicked', () => {
        // Arrange
        const onChange = vi.fn()

        // Act
        render(
          <PluginsPicker {...defaultProps} value={['plugin-1', 'plugin-2']} onChange={onChange} />,
        )
        fireEvent.click(
          screen.getByRole('button', { name: 'plugin.autoUpdate.operation.clearAll' }),
        )

        // Assert
        expect(onChange).toHaveBeenCalledWith([])
      })
    })
  })

  // ============================================================
  // AutoUpdateSetting Main Component Tests
  // ============================================================
  describe('AutoUpdateSetting (index.tsx)', () => {
    const defaultProps = {
      payload: createMockAutoUpdateConfig(),
      onChange: vi.fn(),
    }

    describe('Rendering', () => {
      it('should render update settings header', () => {
        // Act
        render(<AutoUpdateSetting {...defaultProps} />)

        // Assert
        expect(screen.getByText('plugin.autoUpdate.updateSettings')).toBeInTheDocument()
      })

      it('should render automatic updates label', () => {
        // Act
        render(<AutoUpdateSetting {...defaultProps} />)

        // Assert
        expect(screen.getByText('plugin.autoUpdate.automaticUpdates')).toBeInTheDocument()
      })

      it('should render strategy picker', () => {
        // Act
        render(<AutoUpdateSetting {...defaultProps} />)

        // Assert
        expect(
          screen.getByRole('button', { name: /plugin\.autoUpdate\.strategy\.fixOnly\.name/i }),
        ).toBeInTheDocument()
      })

      it('should show time picker when strategy is not disabled', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(screen.getByText('plugin.autoUpdate.updateTime')).toBeInTheDocument()
        expect(screen.getByTestId('time-picker')).toBeInTheDocument()
      })

      it('should hide time picker and plugins selection when strategy is disabled', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.disabled,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(screen.queryByText('plugin.autoUpdate.updateTime')).not.toBeInTheDocument()
        expect(screen.queryByTestId('time-picker')).not.toBeInTheDocument()
      })

      it('should show plugins picker when mode is not update_all', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.partial,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(screen.getByText('plugin.autoUpdate.operation.select')).toBeInTheDocument()
      })

      it('should hide plugins picker when mode is update_all', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.update_all,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(screen.queryByText('plugin.autoUpdate.operation.select')).not.toBeInTheDocument()
      })
    })

    describe('Strategy Description', () => {
      it('should show fixOnly description when strategy is fixOnly', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.strategy.fixOnly.selectedDescription'),
        ).toBeInTheDocument()
      })

      it('should show latest description when strategy is latest', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.latest,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.strategy.latest.selectedDescription'),
        ).toBeInTheDocument()
      })

      it('should show no description when strategy is disabled', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.disabled,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(
          screen.queryByText('plugin.autoUpdate.strategy.fixOnly.selectedDescription'),
        ).not.toBeInTheDocument()
        expect(
          screen.queryByText('plugin.autoUpdate.strategy.latest.selectedDescription'),
        ).not.toBeInTheDocument()
      })
    })

    describe('Plugins Selection', () => {
      it('should show include_plugins when mode is partial', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.partial,
          include_plugins: ['plugin-1', 'plugin-2'],
          exclude_plugins: [],
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.partialUPdate:{"count":2,"num":2}'),
        ).toBeInTheDocument()
      })

      it('should show exclude_plugins when mode is exclude', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.exclude,
          include_plugins: [],
          exclude_plugins: ['plugin-1', 'plugin-2', 'plugin-3'],
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(
          screen.getByText('plugin.autoUpdate.excludeUpdate:{"count":3,"num":3}'),
        ).toBeInTheDocument()
      })
    })

    describe('User Interactions', () => {
      it('should call onChange with updated strategy when strategy changes', async () => {
        // Arrange
        const user = userEvent.setup()
        const onChange = vi.fn()
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

        await user.click(
          screen.getByRole('button', { name: /plugin\.autoUpdate\.strategy\.latest\.name/i }),
        )

        // Assert
        expect(onChange).toHaveBeenCalledWith(
          expect.objectContaining({ strategy_setting: AUTO_UPDATE_STRATEGY.latest }),
        )
      })

      it('should call onChange with updated time when time changes', () => {
        // Arrange
        const onChange = vi.fn()
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

        // Click time picker trigger
        fireEvent.click(screen.getByRole('button', { name: /GMT-5/ }))

        // Set time
        fireEvent.click(screen.getByRole('button', { name: 'Set 10:30' }))

        // Assert
        expect(onChange).toHaveBeenCalled()
      })

      it('should call onChange with 0 when time is cleared', () => {
        // Arrange
        const onChange = vi.fn()
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

        // Click time picker trigger
        fireEvent.click(screen.getByRole('button', { name: /GMT-5/ }))

        // Clear time
        fireEvent.click(screen.getByRole('button', { name: 'Clear' }))

        // Assert
        expect(onChange).toHaveBeenCalled()
      })

      it('should call onChange with include_plugins when in partial mode', () => {
        // Arrange
        const onChange = vi.fn()
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.partial,
          include_plugins: ['existing-plugin'],
        })

        // Act
        render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

        // Click clear all
        fireEvent.click(
          screen.getByRole('button', { name: 'plugin.autoUpdate.operation.clearAll' }),
        )

        // Assert
        expect(onChange).toHaveBeenCalledWith(
          expect.objectContaining({
            include_plugins: [],
          }),
        )
      })

      it('should call onChange with exclude_plugins when in exclude mode', () => {
        // Arrange
        const onChange = vi.fn()
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.exclude,
          exclude_plugins: ['existing-plugin'],
        })

        // Act
        render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

        // Click clear all
        fireEvent.click(
          screen.getByRole('button', { name: 'plugin.autoUpdate.operation.clearAll' }),
        )

        // Assert
        expect(onChange).toHaveBeenCalledWith(
          expect.objectContaining({
            exclude_plugins: [],
          }),
        )
      })

      it('should open account settings when timezone link is clicked', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)
        fireEvent.click(screen.getByText('autoUpdate.changeTimezone'))

        // Assert
        expect(mockSetShowAccountSettingModal).toHaveBeenCalledWith({
          payload: ACCOUNT_SETTING_TAB.PREFERENCES,
        })
      })
    })

    describe('Callback Memoization', () => {
      it('minuteFilter should filter to 15 minute intervals', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // The minuteFilter is passed to TimePicker internally
        // We verify the component renders correctly
        expect(screen.getByTestId('time-picker')).toBeInTheDocument()
      })

      it('handleChange should preserve other config values', () => {
        // Arrange
        const onChange = vi.fn()
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_time_of_day: 36000,
          upgrade_mode: AUTO_UPDATE_MODE.partial,
          include_plugins: ['plugin-1'],
          exclude_plugins: [],
        })

        // Act
        render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

        // Trigger a change (clear plugins)
        fireEvent.click(
          screen.getByRole('button', { name: 'plugin.autoUpdate.operation.clearAll' }),
        )

        // Assert - other values should be preserved
        expect(onChange).toHaveBeenCalledWith(
          expect.objectContaining({
            strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
            upgrade_time_of_day: 36000,
            upgrade_mode: AUTO_UPDATE_MODE.partial,
          }),
        )
      })

      it('handlePluginsChange should not update when mode is update_all', () => {
        // Arrange
        const onChange = vi.fn()
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.update_all,
        })

        // Act
        render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

        // Plugin picker should not be visible in update_all mode
        expect(screen.queryByText('plugin.autoUpdate.operation.clearAll')).not.toBeInTheDocument()
      })
    })

    describe('Memoization Logic', () => {
      it('strategyDescription should update when strategy_setting changes', () => {
        // Arrange
        const payload1 = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })
        const { rerender } = render(<AutoUpdateSetting {...defaultProps} payload={payload1} />)

        // Assert initial
        expect(
          screen.getByText('plugin.autoUpdate.strategy.fixOnly.selectedDescription'),
        ).toBeInTheDocument()

        // Act - change strategy
        const payload2 = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.latest,
        })
        rerender(<AutoUpdateSetting {...defaultProps} payload={payload2} />)

        // Assert updated
        expect(
          screen.getByText('plugin.autoUpdate.strategy.latest.selectedDescription'),
        ).toBeInTheDocument()
      })

      it('plugins should reflect correct list based on upgrade_mode', () => {
        // Arrange
        const partialPayload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.partial,
          include_plugins: ['include-1', 'include-2'],
          exclude_plugins: ['exclude-1'],
        })
        const { rerender } = render(
          <AutoUpdateSetting {...defaultProps} payload={partialPayload} />,
        )

        // Assert - partial mode shows include_plugins count
        expect(
          screen.getByText('plugin.autoUpdate.partialUPdate:{"count":2,"num":2}'),
        ).toBeInTheDocument()

        // Act - change to exclude mode
        const excludePayload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.exclude,
          include_plugins: ['include-1', 'include-2'],
          exclude_plugins: ['exclude-1'],
        })
        rerender(<AutoUpdateSetting {...defaultProps} payload={excludePayload} />)

        // Assert - exclude mode shows exclude_plugins count
        expect(
          screen.getByText('plugin.autoUpdate.excludeUpdate:{"count":1,"num":1}'),
        ).toBeInTheDocument()
      })
    })

    describe('Edge Cases', () => {
      it('should handle empty payload values gracefully', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          include_plugins: [],
          exclude_plugins: [],
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(screen.getByText('plugin.autoUpdate.updateSettings')).toBeInTheDocument()
      })

      it('should handle null timezone gracefully', () => {
        // This tests the timezone! non-null assertion in the component
        // The mock provides a valid timezone, so the component should work
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert - should render without errors
        expect(screen.getByTestId('time-picker')).toBeInTheDocument()
      })

      it('should render timezone offset correctly', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert - should show timezone offset
        expect(screen.getByText('GMT-5')).toBeInTheDocument()
      })
    })

    describe('Upgrade Mode Options', () => {
      it('should render all three upgrade mode options', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(screen.getByText('plugin.autoUpdate.upgradeMode.all')).toBeInTheDocument()
        expect(screen.getByText('plugin.autoUpdate.upgradeMode.exclude')).toBeInTheDocument()
        expect(screen.getByText('plugin.autoUpdate.upgradeMode.partial')).toBeInTheDocument()
      })

      it('should highlight selected upgrade mode', () => {
        // Arrange
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.partial,
        })

        // Act
        render(<AutoUpdateSetting {...defaultProps} payload={payload} />)

        // Assert
        expect(
          screen.getByRole('button', { name: 'plugin.autoUpdate.upgradeMode.all' }),
        ).toHaveAttribute('aria-pressed', 'false')
        expect(
          screen.getByRole('button', { name: 'plugin.autoUpdate.upgradeMode.exclude' }),
        ).toHaveAttribute('aria-pressed', 'false')
        expect(
          screen.getByRole('button', { name: 'plugin.autoUpdate.upgradeMode.partial' }),
        ).toHaveAttribute('aria-pressed', 'true')
      })

      it('should call onChange when upgrade mode is changed', () => {
        // Arrange
        const onChange = vi.fn()
        const payload = createMockAutoUpdateConfig({
          strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
          upgrade_mode: AUTO_UPDATE_MODE.update_all,
        })

        // Act
        render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

        // Click on partial mode
        const partialOption = screen.getByText('plugin.autoUpdate.upgradeMode.partial')
        fireEvent.click(partialOption)

        // Assert
        expect(onChange).toHaveBeenCalledWith(
          expect.objectContaining({
            upgrade_mode: AUTO_UPDATE_MODE.partial,
          }),
        )
      })
    })
  })

  // ============================================================
  // Integration Tests
  // ============================================================
  describe('Integration', () => {
    it('should handle full workflow: enable updates, set time, select plugins', () => {
      // Arrange
      const onChange = vi.fn()
      let currentPayload = createMockAutoUpdateConfig({
        strategy_setting: AUTO_UPDATE_STRATEGY.disabled,
      })

      const { rerender } = render(
        <AutoUpdateSetting payload={currentPayload} onChange={onChange} />,
      )

      // Assert - initially disabled
      expect(screen.queryByTestId('time-picker')).not.toBeInTheDocument()

      // Simulate enabling updates
      currentPayload = createMockAutoUpdateConfig({
        strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        upgrade_mode: AUTO_UPDATE_MODE.partial,
        include_plugins: [],
      })
      rerender(<AutoUpdateSetting payload={currentPayload} onChange={onChange} />)

      // Assert - time picker and plugins visible
      expect(screen.getByTestId('time-picker')).toBeInTheDocument()
      expect(screen.getByText('plugin.autoUpdate.operation.select')).toBeInTheDocument()
    })

    it('should maintain state consistency when switching modes', () => {
      // Arrange
      const onChange = vi.fn()
      const payload = createMockAutoUpdateConfig({
        strategy_setting: AUTO_UPDATE_STRATEGY.fixOnly,
        upgrade_mode: AUTO_UPDATE_MODE.partial,
        include_plugins: ['plugin-1'],
        exclude_plugins: ['plugin-2'],
      })

      // Act
      render(<AutoUpdateSetting payload={payload} onChange={onChange} />)

      // Assert - partial mode shows include_plugins
      expect(
        screen.getByText('plugin.autoUpdate.partialUPdate:{"count":1,"num":1}'),
      ).toBeInTheDocument()
    })
  })
})
