/**
 * setting sync panel，
 */

/**
 * bookmark form
 */
import { useEffect, useRef } from 'react'
import { ArrowDownOutlined, ArrowUpOutlined, SaveOutlined, ClearOutlined } from '@ant-design/icons'
import { Button, Input, Form, Alert, Switch } from 'antd'
import { notification } from '../common/notification'
import Link from '../common/external-link'
import dayjs from 'dayjs'
import eq from 'fast-deep-equal'
import { syncTokenCreateUrls, syncTypes } from '../../common/constants'
import HelpIcon from '../common/help-icon'
import ServerDataStatus from './server-data-status'
import Password from '../common/password'
import { isError } from 'lodash-es'

const FormItem = Form.Item
const e = window.translate

function trim (str) {
  return str ? str.trim() : ''
}

export default function SyncForm (props) {
  const [form] = Form.useForm()
  const prevRef = useRef(null)

  useEffect(() => {
    if (prevRef.current && !eq(prevRef.current, props.formData)) {
      form.resetFields()
    }
    prevRef.current = props.formData
  }, [props.formData])

  const { syncType } = props
  function disabled () {
    if (syncType === syncTypes.cloud) {
      return !props.formData.token
    }
    if (syncType === syncTypes.webdav) {
      const { serverUrl, username, password } = props.formData
      return !serverUrl || !username || !password
    }
    const {
      token,
      gistId
    } = props.formData
    return !token || !gistId
  }

  async function save (res) {
    const { syncType } = props
    const up = {
      [syncType + 'AccessToken']: res.token
    }
    if (res.gistId) {
      up[syncType + 'GistId'] = res.gistId
    } else if (syncType === syncTypes.cloud) {
      up[syncType + 'GistId'] = 'cloud'
    }
    up[syncType + 'SyncPassword'] = res.syncPassword || ''
    if (res.apiUrl) {
      up[syncType + 'ApiUrl'] = res.apiUrl
    } else if (syncType === syncTypes.cloud) {
      up[syncType + 'ApiUrl'] = 'https://sync.electerm.org/api/sync'
      // up[syncType + 'ApiUrl'] = 'http://127.0.0.1:5678/api/sync'
    }
    if (res.proxy) {
      up[syncType + 'Proxy'] = res.proxy
    } else {
      up[syncType + 'Proxy'] = ''
    }

    // Handle WebDAV specific fields
    if (syncType === syncTypes.webdav) {
      up[syncType + 'ServerUrl'] = res.serverUrl || ''
      up[syncType + 'Username'] = res.username || ''
      up[syncType + 'Password'] = res.password || ''
      up[syncType + 'SkipVerify'] = res.skipVerify || false
    }

    window.store.updateSyncSetting(up)
    const test = await window.store.testSyncToken(syncType, res.gistId)
    if (isError(test)) {
      return notification.error({
        message: test.message || 'Request failed',
        description: test.stack || 'Request failed'
      })
    }
    // if (!res.gistId && syncType !== syncTypes.custom && syncType !== syncTypes.cloud) {
    //   window.store.createGist(syncType)
    // }
  }

  function upload () {
    window
      .store
      .uploadSetting(props.syncType)
      .catch(window.store.onError)
  }

  function download () {
    window
      .store
      .downloadSetting(props.syncType)
      .catch(window.store.onError)
  }

  // onChangeAutoSync = checked => {
  //   this.window.store.updateSyncSetting({
  //     autoSync: checked
  //   })
  // }

  function getTokenCreateGuideUrl () {
    return syncTokenCreateUrls[props.syncType]
  }

  function renderGistUrl () {
    if (!props.formData.url) {
      return null
    }
    return (
      <Link to={props.formData.url}>Check gist</Link>
    )
  }

  const {
    lastSyncTime = ''
  } = props.formData

  const isCustom = syncType === syncTypes.custom
  const timeFormatted = lastSyncTime
    ? dayjs(lastSyncTime).format('YYYY-MM-DD HH:mm:ss')
    : '-'
  const customNameMapper = {
    token: 'JWT Secret',
    gist: 'User ID'
  }
  const otherNameMapper = {
    token: 'access token',
    gistId: 'gist id'
  }
  function createLabel (name, text) {
    return (
      <span>
        {isCustom ? (customNameMapper[name] || name) : name}
        <HelpIcon link={getTokenCreateGuideUrl()} />
      </span>
    )
  }
  function createPlaceHolder (name) {
    if (syncType === syncTypes.custom) {
      return customNameMapper[name]
    }
    return syncType + ' ' + otherNameMapper[name]
  }
  function createId (name) {
    return 'sync-input-' + name + '-' + syncType
  }
  function renderWarning () {
    if (syncType === syncTypes.gitee) {
      return (
        <Alert
          title={
            <span>
              Gitee data sync is not recommended. For more information, please refer to the
              <Link to='https://github.com/electerm/electerm/wiki/gitee-data-sync-warning' className='mg1l'>
                wiki
              </Link>
              .
            </span>
          }
          type='warning'
          showIcon
          className='mg1b'
        />
      )
    }
    return null
  }
  function createUrlItem () {
    if (syncType === syncTypes.cloud) {
      return (
        <p>
          <Link to='https://sync.electerm.org'>
            https://sync.electerm.org[Beta]
          </Link>
        </p>
      )
    }
    if (syncType === syncTypes.webdav) {
      return createWebdavItems()
    }
    if (syncType !== syncTypes.custom) {
      return null
    }
    return (
      <FormItem
        label={createLabel('API Url')}
        name='apiUrl'
        normalize={trim}
        rules={[{
          max: 200, message: '200 chars max'
        }]}
      >
        <Input
          placeholder='API Url'
          id='sync-input-url-custom'
        />
      </FormItem>
    )
  }
  function createWebdavItems () {
    return (
      <div>
        <FormItem
          label={createLabel('URL')}
          name='serverUrl'
          normalize={trim}
          rules={[{
            max: 500, message: '500 chars max'
          }, {
            required: true, message: 'Server URL is required'
          }]}
        >
          <Input
            placeholder='https://your-webdav-server.com/remote.php/dav/files/username'
            id='sync-input-webdav-server-url'
          />
        </FormItem>
        <FormItem
          label={createLabel(e('username'))}
          name='username'
          normalize={trim}
          rules={[{
            max: 200, message: '200 chars max'
          }, {
            required: true, message: 'Username is required'
          }]}
        >
          <Input
            placeholder='WebDAV username'
            id='sync-input-webdav-username'
          />
        </FormItem>
        <FormItem
          label={createLabel('Skip SSL verify')}
          name='skipVerify'
          valuePropName='checked'
        >
          <Switch />
        </FormItem>
        <FormItem
          label={createLabel(e('password'))}
          name='password'
          normalize={trim}
          rules={[{
            max: 200, message: '200 chars max'
          }, {
            required: true, message: 'Password is required'
          }]}
        >
          <Password
            placeholder='WebDAV password'
            id='sync-input-webdav-password'
          />
        </FormItem>
      </div>
    )
  }
  const desc = syncType === syncTypes.custom
    ? 'jwt secret'
    : syncType === syncTypes.webdav
      ? 'WebDAV credentials'
      : 'personal access token'
  const idDesc = syncType === syncTypes.custom
    ? 'user id'
    : syncType === syncTypes.webdav
      ? 'WebDAV server'
      : 'gist ID'
  const tokenLabel = createLabel('token', desc)
  const gistLabel = createLabel('gist', idDesc)
  const syncPasswordName = e('encrypt') + ' ' + e('password')
  const syncPasswordLabel = createLabel(syncPasswordName, '')
  function createIdItem () {
    if (syncType === syncTypes.cloud || syncType === syncTypes.webdav) {
      return null
    }
    return (
      <FormItem
        label={gistLabel}
        name='gistId'
        required
        normalize={trim}
        rules={[{
          max: 100, message: '100 chars max'
        }]}
      >
        <Input
          placeholder={createPlaceHolder('gistId')}
          id={createId('gistId')}
        />
      </FormItem>
    )
  }
  function createPasswordItem () {
    if (syncType === syncTypes.cloud) {
      return null
    }
    return (
      <FormItem
        label={syncPasswordLabel}
        hasFeedback
        name='syncPassword'
        normalize={trim}
        rules={[{
          max: 100, message: '100 chars max'
        }]}
      >
        <Password
          placeholder={syncType + ' ' + syncPasswordName}
        />
      </FormItem>
    )
  }
  function createProxyItem () {
    return (
      <FormItem
        label='Proxy'
        name='proxy'
        normalize={trim}
        rules={[{
          max: 200, message: '200 chars max'
        }]}
      >
        <Input
          placeholder='socks5://127.0.0.1:1080'
          id={createId('proxy')}
        />
      </FormItem>
    )
  }
  const sprops = {
    type: syncType,
    status: props.serverStatus
  }
  function createTokenItem () {
    if (syncType === syncTypes.webdav) {
      return null
    }
    return (
      <FormItem
        label={tokenLabel}
        hasFeedback
        name='token'
        normalize={trim}
        rules={[{
          max: 1100, message: '1100 chars max'
        }, {
          required: true, message: createPlaceHolder('token') + ' required'
        }]}
      >
        <Password
          placeholder={createPlaceHolder('token')}
          id={createId('token')}
        />
      </FormItem>
    )
  }
  return (
    <Form
      onFinish={save}
      form={form}
      className='form-wrap pd1x'
      name={'setting-sync-form' + syncType}
      layout='vertical'
      initialValues={props.formData}
    >
      {renderWarning()}
      {createUrlItem()}
      {createTokenItem()}
      {
        createIdItem()
      }
      {
        createPasswordItem()
      }
      {
        createProxyItem()
      }
      <FormItem>
        <p>
          <Button
            type='dashed'
            className='mg1r mg1b sync-btn-save'
            htmlType='submit'
            icon={<SaveOutlined />}
          >{e('save')}
          </Button>
          {/* <Button
            type='dashed'
            onClick={this.sync}
            disabled={this.disabled()}
            className='mg1r'
            loading={isSyncingSetting}
            icon='swap'
          >{e('sync')}</Button> */}
          <Button
            type='dashed'
            onClick={upload}
            disabled={disabled()}
            className='mg1r mg1b sync-btn-up'
            icon={<ArrowUpOutlined />}
          >{e('uploadSettings')}
          </Button>
          <Button
            type='dashed'
            onClick={download}
            disabled={disabled()}
            className='mg1r mg1b sync-btn-down'
            icon={<ArrowDownOutlined />}
          >{e('downloadSettings')}
          </Button>
          <Button
            type='dashed'
            onClick={window.store.handleClearSyncSetting}
            disabled={disabled()}
            className='mg1r mg1b sync-btn-clear'
            icon={<ClearOutlined />}
          >{e('clear')}
          </Button>
        </p>
        <ServerDataStatus {...sprops} />
        <p>
          {e('lastSyncTime')}: {timeFormatted}
        </p>
        <p>
          {renderGistUrl()}
        </p>
      </FormItem>
    </Form>
  )
}
