'use client'
import type { FC } from 'react'
import type { AutoUpdateConfig } from './types'
import type { TriggerParams } from '@/app/components/base/date-and-time-picker/types'
import { cn } from '@langgenius/dify-ui/cn'
import { RiTimeLine } from '@remixicon/react'
import { useQuery } from '@tanstack/react-query'
import * as React from 'react'
import { useCallback, useMemo } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import TimePicker from '@/app/components/base/date-and-time-picker/time-picker'
import { convertTimezoneToOffsetStr } from '@/app/components/base/date-and-time-picker/utils/dayjs'
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card'
import { useModalContextSelector } from '@/context/modal-context'
import { userProfileQueryOptions } from '@/features/account-profile/client'
import Label from '../label'
import PluginsPicker from './plugins-picker'
import StrategyPicker from './strategy-picker'
import { AUTO_UPDATE_MODE, AUTO_UPDATE_STRATEGY } from './types'
import { convertLocalSecondsToUTCDaySeconds, convertUTCDaySecondsToLocalSeconds, dayjsToTimeOfDay, timeOfDayToDayjs } from './utils'

const i18nPrefix = 'autoUpdate'

type Props = Readonly<{
  payload: AutoUpdateConfig
  onChange: (payload: AutoUpdateConfig) => void
}>

const SettingTimeZone: FC<{
  children?: React.ReactNode
}> = ({
  children,
}) => {
  const setShowAccountSettingModal = useModalContextSelector(s => s.setShowAccountSettingModal)
  return (
    <button
      type="button"
      className="cursor-pointer border-none bg-transparent p-0 text-left body-xs-regular text-text-accent focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:outline-hidden"
      onClick={() => setShowAccountSettingModal({ payload: ACCOUNT_SETTING_TAB.LANGUAGE })}
    >
      {children}
    </button>
  )
}
const AutoUpdateSetting: FC<Props> = ({
  payload,
  onChange,
}) => {
  const { t } = useTranslation()
  const { data: timezone } = useQuery({
    ...userProfileQueryOptions(),
    select: data => data.profile.timezone ?? undefined,
  })

  const {
    strategy_setting,
    upgrade_time_of_day,
    upgrade_mode,
    exclude_plugins,
    include_plugins,
  } = payload

  const minuteFilter = useCallback((minutes: string[]) => {
    return minutes.filter((m) => {
      const time = Number.parseInt(m, 10)
      return time % 15 === 0
    })
  }, [])
  const strategyDescription = useMemo(() => {
    switch (strategy_setting) {
      case AUTO_UPDATE_STRATEGY.fixOnly:
        return t(`${i18nPrefix}.strategy.fixOnly.selectedDescription`, { ns: 'plugin' })
      case AUTO_UPDATE_STRATEGY.latest:
        return t(`${i18nPrefix}.strategy.latest.selectedDescription`, { ns: 'plugin' })
      default:
        return ''
    }
  }, [strategy_setting, t])

  const plugins = useMemo(() => {
    switch (upgrade_mode) {
      case AUTO_UPDATE_MODE.partial:
        return include_plugins
      case AUTO_UPDATE_MODE.exclude:
        return exclude_plugins
      default:
        return []
    }
  }, [upgrade_mode, exclude_plugins, include_plugins])

  const handlePluginsChange = useCallback((newPlugins: string[]) => {
    if (upgrade_mode === AUTO_UPDATE_MODE.partial) {
      onChange({
        ...payload,
        include_plugins: newPlugins,
      })
    }
    else if (upgrade_mode === AUTO_UPDATE_MODE.exclude) {
      onChange({
        ...payload,
        exclude_plugins: newPlugins,
      })
    }
  }, [payload, upgrade_mode, onChange])
  const handleChange = useCallback((key: keyof AutoUpdateConfig) => {
    return (value: AutoUpdateConfig[keyof AutoUpdateConfig]) => {
      onChange({
        ...payload,
        [key]: value,
      })
    }
  }, [payload, onChange])

  const renderTimePickerTrigger = useCallback(({ inputElem, onClick, isOpen }: TriggerParams) => {
    return (
      <button
        type="button"
        className="group flex h-8 w-[160px] cursor-pointer items-center justify-between rounded-lg border-none bg-components-input-bg-normal px-2 text-left hover:bg-state-base-hover-alt focus-visible:ring-1 focus-visible:ring-components-input-border-active focus-visible:outline-hidden"
        onClick={onClick}
      >
        <div className="flex w-0 grow items-center gap-x-1">
          <RiTimeLine className={cn(
            'size-4 shrink-0 text-text-tertiary',
            isOpen ? 'text-text-secondary' : 'group-hover:text-text-secondary',
          )}
          />
          {inputElem}
        </div>
        <div className="system-sm-regular text-text-tertiary">{convertTimezoneToOffsetStr(timezone)}</div>
      </button>
    )
  }, [timezone])

  return (
    <div className="self-stretch px-6">
      <div className="my-3 flex items-center">
        <div className="system-xs-medium-uppercase text-text-tertiary">{t(`${i18nPrefix}.updateSettings`, { ns: 'plugin' })}</div>
        <div className="ml-2 h-px grow bg-divider-subtle"></div>
      </div>

      <div className="space-y-4">
        <div className="flex items-center justify-between">
          <Label label={t(`${i18nPrefix}.automaticUpdates`, { ns: 'plugin' })} description={strategyDescription} />
          <StrategyPicker value={strategy_setting} onChange={handleChange('strategy_setting')} />
        </div>
        {strategy_setting !== AUTO_UPDATE_STRATEGY.disabled && (
          <>
            <div className="flex items-center justify-between">
              <Label label={t(`${i18nPrefix}.updateTime`, { ns: 'plugin' })} />
              <div className="flex flex-col items-end">
                <TimePicker
                  value={timeOfDayToDayjs(convertUTCDaySecondsToLocalSeconds(upgrade_time_of_day, timezone!))}
                  timezone={timezone}
                  onChange={v => handleChange('upgrade_time_of_day')(convertLocalSecondsToUTCDaySeconds(dayjsToTimeOfDay(v), timezone!))}
                  onClear={() => handleChange('upgrade_time_of_day')(convertLocalSecondsToUTCDaySeconds(0, timezone!))}
                  title={t(`${i18nPrefix}.updateTime`, { ns: 'plugin' })}
                  minuteFilter={minuteFilter}
                  renderTrigger={renderTimePickerTrigger}
                  placement="bottom-end"
                />
                <div className="mt-1 text-right body-xs-regular text-text-tertiary">
                  <Trans
                    i18nKey={`${i18nPrefix}.changeTimezone`}
                    ns="plugin"
                    components={{
                      setTimezone: <SettingTimeZone />,
                    }}
                  />
                </div>
              </div>
            </div>
            <div>
              <Label label={t(`${i18nPrefix}.specifyPluginsToUpdate`, { ns: 'plugin' })} />
              <div className="mt-1 flex w-full items-start justify-between gap-2">
                {[AUTO_UPDATE_MODE.update_all, AUTO_UPDATE_MODE.exclude, AUTO_UPDATE_MODE.partial].map(option => (
                  <OptionCard
                    key={option}
                    title={t(`${i18nPrefix}.upgradeMode.${option}`, { ns: 'plugin' })}
                    onSelect={() => handleChange('upgrade_mode')(option)}
                    selected={upgrade_mode === option}
                    className="flex-1"
                  />
                ))}
              </div>

              {upgrade_mode !== AUTO_UPDATE_MODE.update_all && (
                <PluginsPicker
                  value={plugins}
                  onChange={handlePluginsChange}
                  updateMode={upgrade_mode}
                />
              )}
            </div>
          </>
        )}
      </div>
    </div>
  )
}
export default React.memo(AutoUpdateSetting)
