import React from 'react';
import { CloudUploadIcon, FolderOpenIcon, RefreshIcon, SaveIcon } from '@heroicons/react/outline';
import GreyRowBox from '@/components/elements/GreyRowBox';
import Input, { Textarea } from '@/components/elements/Input';
import Select from '@/components/elements/Select';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import Switch from '@/components/elements/Switch';
import { Button } from '@/components/elements/button/index';
import { importTypeLabels } from '../constants';
import { ProfileDraft, protocolDefaults } from '../types';
import ImporterField from './ImporterField';

type DraftSetter = <K extends keyof ProfileDraft>(key: K, value: ProfileDraft[K]) => void;

interface Props {
  draft: ProfileDraft;
  editingId: number | null;
  selectedItems: string[];
  importing: boolean;
  testing: boolean;
  saving: boolean;
  onChange: DraftSetter;
  onProtocolChange: (protocol: ProfileDraft['protocol']) => void;
  onImportTypeChange: (importType: ProfileDraft['import_type']) => void;
  onBrowse: () => void;
  onTestConnection: () => void;
  onSaveProfile: () => void;
  onStartImport: () => void;
}

export default ({
  draft,
  editingId,
  selectedItems,
  importing,
  testing,
  saving,
  onChange,
  onProtocolChange,
  onImportTypeChange,
  onBrowse,
  onTestConnection,
  onSaveProfile,
  onStartImport,
}: Props) => (
  <GreyRowBox $hoverable={false} className={'relative flex-col !items-stretch !p-4'}>
    <SpinnerOverlay visible={importing} />

    <div className={'space-y-4'}>
      <section>
        <div className={'grid gap-3 md:grid-cols-2'}>
          <ImporterField label={'Protocol'}>
            <Select
              value={draft.protocol}
              onChange={(e) => onProtocolChange(e.currentTarget.value as ProfileDraft['protocol'])}
            >
              <option value={'sftp'}>SFTP</option>
              <option value={'ftp'}>FTP</option>
              <option value={'scp'}>SCP</option>
            </Select>
          </ImporterField>
          <ImporterField label={'Authentication'}>
            <Select
              value={draft.auth_method}
              disabled={draft.protocol === 'ftp'}
              onChange={(e) => onChange('auth_method', e.currentTarget.value as ProfileDraft['auth_method'])}
            >
              <option value={'password'}>Password</option>
              <option value={'ssh_key'}>SSH Key</option>
            </Select>
          </ImporterField>
          <ImporterField label={'Hostname'}>
            <Input
              type={'text'}
              value={draft.hostname}
              placeholder={'example.com'}
              onChange={(e) => onChange('hostname', e.currentTarget.value)}
            />
          </ImporterField>
          <ImporterField label={'Port'}>
            <Input
              type={'number'}
              value={draft.port}
              placeholder={protocolDefaults[draft.protocol]}
              onChange={(e) => onChange('port', e.currentTarget.value)}
            />
          </ImporterField>
          <ImporterField label={'Username'}>
            <Input
              type={'text'}
              value={draft.username}
              placeholder={'root'}
              onChange={(e) => onChange('username', e.currentTarget.value)}
            />
          </ImporterField>
          {draft.auth_method === 'password' ? (
            <ImporterField label={'Password'}>
              <Input
                type={'password'}
                value={draft.password}
                placeholder={draft.has_password ? 'Saved password' : 'Password'}
                onChange={(e) => onChange('password', e.currentTarget.value)}
              />
            </ImporterField>
          ) : (
            <ImporterField label={'SSH Key Passphrase'} description={'Leave blank if the key has no passphrase.'}>
              <Input
                type={'password'}
                value={draft.ssh_key_passphrase}
                placeholder={draft.has_ssh_key_passphrase ? 'Saved passphrase' : 'Optional'}
                onChange={(e) => onChange('ssh_key_passphrase', e.currentTarget.value)}
              />
            </ImporterField>
          )}
          {draft.auth_method === 'ssh_key' && (
            <ImporterField label={'SSH Private Key'} className={'md:col-span-2'}>
              <Textarea
                rows={6}
                value={draft.ssh_key}
                placeholder={draft.has_ssh_key ? 'Saved private key' : '-----BEGIN OPENSSH PRIVATE KEY-----'}
                className={'font-mono text-xs'}
                onChange={(e) => onChange('ssh_key', e.currentTarget.value)}
              />
            </ImporterField>
          )}
        </div>
      </section>

      <section className={'border-t border-neutral-700 pt-4'}>
        <div className={'mb-2 flex justify-end'}>
          <Button.Text type={'button'} size={Button.Sizes.Small} onClick={onBrowse}>
            <FolderOpenIcon className={'mr-2 h-4 w-4'} />
            Browse Remote
          </Button.Text>
        </div>
        <div className={'grid gap-3 md:grid-cols-2'}>
          <ImporterField label={'Profile Name'}>
            <Input
              type={'text'}
              value={draft.name}
              placeholder={'Production server'}
              onChange={(e) => onChange('name', e.currentTarget.value)}
            />
          </ImporterField>
          <ImporterField label={'Import Type'}>
            <Select
              value={draft.import_type}
              onChange={(e) => onImportTypeChange(e.currentTarget.value as ProfileDraft['import_type'])}
            >
              <option value={'full_server'}>Full Server</option>
              <option value={'directory_only'}>Directory Only</option>
              <option value={'selected_path'}>Selected Files</option>
            </Select>
          </ImporterField>
          <ImporterField label={'Progress Mode'}>
            <Select
              value={draft.progress_mode}
              onChange={(e) => onChange('progress_mode', e.currentTarget.value as ProfileDraft['progress_mode'])}
            >
              <option value={'live'}>Live</option>
              <option value={'scan'}>Scan First</option>
            </Select>
          </ImporterField>
        </div>

        {draft.import_type !== 'full_server' && (
          <div className={'mt-3 grid gap-3 md:grid-cols-2'}>
            <ImporterField
              label={'Source Directory'}
              description={
                draft.import_type === 'selected_path' && selectedItems.length > 0
                  ? `${selectedItems.length} selected remote item(s).`
                  : undefined
              }
            >
              <div className={'flex gap-2'}>
                <Input
                  type={'text'}
                  value={draft.source_directory}
                  placeholder={'/home/container'}
                  onChange={(e) => onChange('source_directory', e.currentTarget.value)}
                />
                <Button.Text type={'button'} size={Button.Sizes.Small} onClick={onBrowse}>
                  Browse
                </Button.Text>
              </div>
            </ImporterField>
            <ImporterField label={'Destination Directory'}>
              <Input
                type={'text'}
                value={draft.destination_directory}
                placeholder={'/'}
                onChange={(e) => onChange('destination_directory', e.currentTarget.value)}
              />
            </ImporterField>
          </div>
        )}
      </section>

      <section className={'border-t border-neutral-700 pt-4'}>
        <div className={'space-y-3'}>
          <ImporterField label={'Host Key Fingerprint'}>
            <Input
              type={'password'}
              value={draft.host_key_fingerprint}
              placeholder={'SHA256:...'}
              onChange={(e) => onChange('host_key_fingerprint', e.currentTarget.value)}
            />
          </ImporterField>
        </div>
      </section>

      <div
        className={
          'flex flex-col gap-3 border-t border-neutral-700 pt-4 sm:flex-row sm:items-center sm:justify-between'
        }
      >
        <div className={'flex items-center gap-2'}>
          <Switch
            name={'wipe-server'}
            defaultChecked={draft.wipe}
            key={draft.wipe ? 'wipe-on' : 'wipe-off'}
            onChange={() => onChange('wipe', !draft.wipe)}
          />
          <span className={'text-sm font-medium text-white'}>Wipe server</span>
        </div>
        <div className={'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end'}>
          <Button.Text type={'button'} onClick={onTestConnection} disabled={testing || importing}>
            <RefreshIcon className={'mr-2 h-4 w-4'} />
            {testing ? 'Testing...' : 'Test Connection'}
          </Button.Text>
          <Button.Text type={'button'} onClick={onSaveProfile} disabled={saving || importing}>
            <SaveIcon className={'mr-2 h-4 w-4'} />
            {saving ? 'Saving...' : editingId ? 'Update Profile' : 'Save Profile'}
          </Button.Text>
          <Button type={'button'} onClick={onStartImport} disabled={importing}>
            <CloudUploadIcon className={'mr-2 h-4 w-4'} />
            {importing ? 'Importing...' : `Start ${importTypeLabels[draft.import_type]}`}
          </Button>
        </div>
      </div>
    </div>
  </GreyRowBox>
);
