import React, {KeyboardEvent, useEffect, useRef, useState} from 'react';
import { faSearch } from '@fortawesome/free-solid-svg-icons/faSearch';
import { faUser } from '@fortawesome/free-solid-svg-icons/faUser';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { storiesOf } from '@storybook/react';
import { FormHandles } from '@devesharp/unform-core';
import { Form } from '@devesharp/unform-web';
import styled from 'styled-components';
import { AppProvider } from '../AppProvider';
import { LoaderIcon } from '../LoaderIcon';
import { maskValue } from '../MaskText/mask.utils';
import { FormStyle } from '../styles';
import { CustomComponentInput } from './__mocks__/InputCustom';
import { ICustomInputProps, Input, ViewPasswordToggle } from './index';
import {NumberFormat, OnlyNumbers} from "@devesharp/react-utils/lib/Utils";

const css = styled.div;

const Style = css`
   background: white !important;
`;

function NumberMask(_value: string | number, decimals = 2 ): string {
   if (typeof _value === 'number') {
      _value = _value.toFixed(decimals).toString();
   }

   const value = _value || '';

   if (value === '') return value;

   let newValOnlyNumbers = OnlyNumbers(value);

   if (newValOnlyNumbers.length > 15) {
      newValOnlyNumbers = newValOnlyNumbers.substr(0, 15);
   }

   return NumberFormat(Number(newValOnlyNumbers) / 10 ** decimals, decimals).toString();
}

function convertNumber(text, decimals = 4) {
   let newText = text;
   let inteiro = newText.indexOf(',') == -1 ? newText : newText.slice(0, newText.indexOf(','));
   let decimais = newText.indexOf(',') == -1 ? null : newText.slice(newText.indexOf(',') + 1).replace(/,/g, '');

   if(decimais != null) {
      if(decimais.length) {
         return NumberFormat(OnlyNumbers(inteiro), 0, ',', ' ') + ',' + OnlyNumbers(decimais.substring(0, decimals));
      } else {

         if(!inteiro.length) {
            return '0,';
         }

         return NumberFormat(OnlyNumbers(inteiro), 0, ',', ' ') + ',';
      }
   }

   return NumberFormat(OnlyNumbers(inteiro), 0, ',', ' ');
}

storiesOf('Components/Input', module)
   .add('default', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input title="Input" />
               </div>
            </div>
         </Style>
      );
   })
   .add('use advancedMask', () => {
      const special = [',','.']
      
      function removeCharAt(string, i) {
         var tmp = string.split(''); // convert to an array
         tmp.splice(i - 1 , 1); // remove 1 element from the array (adjusting for non-zero-indexed counts)
         return tmp.join(''); // reconstruct the string
      }

      function removeCaracter(originalText, position): string {
         let newText = removeCharAt(originalText, position+1);

         if(special.find(i => i == originalText[position])) {
            newText = removeCharAt(newText, position);
         }

         return newText;
      }
      
      function onMask(text: string, afterText: string, cursorPointer: number, currentKey: string): any {
         if (text == '' || !text) return [text, cursorPointer ];

          let textMask = convertNumber(text);
          let textOldMask = convertNumber(afterText);
          
         if (currentKey == 'Backspace') {
            if (textMask == afterText) {
               text = removeCaracter(text, cursorPointer-1);
               textMask = convertNumber(text);
               cursorPointer = cursorPointer - 1;
            }
         }

         if (currentKey == 'Backspace') {
            if (textMask == afterText) {
               text = removeCaracter(text, cursorPointer-1);
               textMask = convertNumber(text);
               cursorPointer = cursorPointer - 1;
            }
         }
         
         if (textMask.length > text.length) {
            cursorPointer += 1;
         }
         
         if (textMask.length == textOldMask.length && currentKey == ',') {
            cursorPointer -= 1;
         }
         
         return [textMask, cursorPointer];
      }
      
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input title="Input" advancedMask={onMask} />
               </div>
            </div>
         </Style>
      );
   })
   .add('default2', () => {
      const inputRef = useRef<HTMLInputElement>(null);
      const charRef = useRef<string>(null);
      const inputOldValueRef = useRef<string>('');
      // function onChange(e: any) {
      //    var caretPos = e.target.selectionStart;
      //    var value = e.target.value;
      //   
      //    if (charRef.current === 'Backspace') {
      //       console.log(inputOldValueRef.current[caretPos]);
      //    }
      // }
      
      function onChange2(e: any) {
         charRef.current = e.key;
         inputOldValueRef.current = e.target.value;
         
         setTimeout(() => {
            var caretPos = e.target.selectionStart;
            var value = e.target.value;
            console.log(caretPos);
            console.log(value);
            e.target.value = 1;
         }, 0);
         // console.log(charRef.current);
         // mask
      }
      
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <input ref={inputRef} onKeyDown={onChange2} />
               </div>
            </div>
         </Style>
      );
   })
   .add('default with state', () => {
      const [value, setValue] = useState('default text');

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input title="Input" onInput={setValue} value={value} />
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with async', () => {
      const formRef = useRef<FormHandles>();

      useEffect(() => {
         setTimeout(() => {
            formRef.current.setFieldValue('default', 'Field Invalid');
         }, 2000);
      }, []);

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '10000' }} ref={formRef}>
                     <Input
                        name="default"
                        onChange={(ev) => {
                           console.log('sdsd', ev.target.value);
                        }}
                        onInput={(ev) => {
                           console.log('input', ev);
                        }}
                     />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('prefix with JSX', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input prefix={<FontAwesomeIcon icon={faUser} />} />
               </div>
            </div>
         </Style>
      );
   })
   .add('prefix with text', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input prefix="R$" />
               </div>
            </div>
         </Style>
      );
   })
   .add('suffix with JSX', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input suffix={<FontAwesomeIcon icon={faSearch} />} />
               </div>
            </div>
         </Style>
      );
   })
   .add('suffix with text', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input suffix="m³" />
               </div>
            </div>
         </Style>
      );
   })
   .add('suffix with loading', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input loading />
               </div>
            </div>
         </Style>
      );
   })
   .add('title', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input title="Full Name" />
               </div>
            </div>
         </Style>
      );
   })
   .add('textRight', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input textRight value="Text Right" />
               </div>
            </div>
         </Style>
      );
   })
   .add('with number', () => {
      const [value, setValue] = useState(100.1023);
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="number" value={value} onInput={setValue} />
               </div>
            </div>
         </Style>
      );
   })
   .add('with number decimals', () => {
      const [value, setValue] = useState('10000');
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="number" decimals={4} value={value} onInput={setValue} />
               </div>
            </div>
         </Style>
      );
   })
   .add('with CEP', () => {
      const [value, setValue] = useState('08871220');

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="CEP" value={value} onInput={setValue} />
               </div>
            </div>
         </Style>
      );
   })
   .add('with CNPJ', () => {
      const [value, setValue] = useState('26576255000191');

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="CNPJ" value={value} onInput={setValue} />
               </div>
            </div>
         </Style>
      );
   })
   .add('with CPF', () => {
      const [value, setValue] = useState('26576255000191');

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="CPF" value={value} onInput={setValue} />
               </div>
            </div>
         </Style>
      );
   })
   .add('with RG', () => {
      const [value, setValue] = useState('461273317');

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="RG" value={value} onInput={setValue} />
               </div>
            </div>
         </Style>
      );
   })
   .add('with phone', () => {
      const [value, setValue] = useState('1188881234');
      const [value2, setValue2] = useState('11988881234');

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="phone" value={value} onInput={setValue} />
                  <Input mask="phone" value={value2} onInput={setValue2} />
               </div>
            </div>
         </Style>
      );
   })
   .add('with password', () => {
      const [value, setValue] = useState('1188881234');

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="phone" value={value} onInput={setValue} password />
               </div>
            </div>
         </Style>
      );
   })
   .add('no spaces', () => {
      const [value, setValue] = useState(' email @simple. com. br');

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="no-spaces" value={value} onInput={setValue} />
               </div>
            </div>
         </Style>
      );
   })
   .add('with type hidden', () => {
      const [value, setValue] = useState('10000');
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input mask="number" value={value} onInput={setValue} type="hidden" />
               </div>
            </div>
         </Style>
      );
   })
   .add('with error', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Input error="field invalid" />
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - default', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}}>
                     <Input name="name1" title="Input" />
                     <Input name="name2" title="Input" />
                     <Input name="name3" title="Input" />
                     <Input name="name4" title="Input" />
                     <Input name="name5" title="Input" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with number', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={(data) => console.log(data)} initialData={{ default: '10000' }}>
                     <Input mask="number" name="default" />
                     <button>asdasd</button>
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with number decimals', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '10000' }}>
                     <Input mask="number" decimals={4} name="default" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with CEP', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '08871220' }}>
                     <Input mask="CEP" name="default" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with CNPJ', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '26576255000191' }}>
                     <Input mask="CNPJ" name="default" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with CPF', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '26576255000191' }}>
                     <Input mask="CPF" name="default" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with RG', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '461273317' }}>
                     <Input mask="RG" name="default" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with phone', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '1188881234', number11Digits: '11988881234' }}>
                     <Input mask="phone" name="default" />
                     <Input mask="phone" name="number11Digits" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - no spaces', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: ' email @simple. com. br' }}>
                     <Input mask="no-spaces" name="default" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('unform - with error', () => {
      const formRef = useRef<FormHandles>();

      useEffect(() => {
         formRef.current.setFieldError('default', 'Field Invalid');
      }, []);

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '10000' }} ref={formRef}>
                     <Input name="default" />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('with CustomComponent', () => {
      const formRef = useRef<FormHandles>();

      useEffect(() => {
         formRef.current.setFieldError('default', 'Field Invalid');
      }, []);

      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <Form onSubmit={() => {}} initialData={{ default: '10000' }} ref={formRef}>
                     <Input name="default" title="Custom Input" CustomComponent={CustomComponentInput} />
                  </Form>
               </div>
            </div>
         </Style>
      );
   })
   .add('with CustomComponent in AppProvider', () => {
      return (
         <Style>
            <div className="row">
               <div className="m-4 col-sm-3">
                  <AppProvider initialData={{ customComponents: { Input: CustomComponentInput } }}>
                     <Input title="Custom Input" />
                  </AppProvider>
               </div>
            </div>
         </Style>
      );
   });
