import {
  useEffect,
  useState,
} from 'react';

import {
  FileIcon,
  LinkIcon,
  Loader2,
  Trash2,
  UploadIcon,
} from 'lucide-react';
import { BiMicrophone } from 'react-icons/bi';

import { rpc } from '@/api/request';
import { audioRecordDialogRef } from '@/components/AudioRecordDialog';
import { Button } from '@/components/ui/button';
import { ButtonGroup } from '@/components/ui/button-group';
import { useAppConfig } from '@/contexts/AppConfigContext';
import { Lang } from '@/lang/Lang';
import { copyTextToClipboard } from '@/utils/helpers';

import DataDescription from '../components/DataDescription';
import DataLabel from '../components/DataLabel';
import { ItemDataProps } from '../types';
import AudioPlayer from './components/AudioPlayer';
import ImagePreview from './components/ImagePreview';
import VideoPlayer from './components/VideoPlayer';

async function selectFile(accept: string): Promise<File | null> {
  return new Promise((resolve) => {
    // Создание input
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = accept; // Только изображения
    input.style.display = 'none'; // Не показываем на странице

    // Обработчик выбора файла
    input.addEventListener('change', () => {
      const file = input.files?.[0] ?? null;

      // Очистка: удаление input
      input.remove();

      resolve(file);
    });
    input.onerror = () => {

      resolve(null);
    };
    input.onabort = () => {
      resolve(null);
    };
    input.onerror = () => {
      resolve(null);
    };
    input.onabort = () => {
      resolve(null);
    };

    // Добавляем на страницу и вызываем выбор файла
    document.body.appendChild(input);
    input.click();
  });
}

export const FileData = (props: ItemDataProps) => {


  const [localValue, setLocalValue] = useState(props.getValue());

  useEffect(() => {
    props.setValue(localValue);
  }, [localValue]);




  const [uploading, setUploading] = useState<boolean>(false);





  const delFile = () => {



    if (props.structure?.type == "fileImageLink") {
      setLocalValue("");
      return;
    }

    if (props.structure?.type == "fileAudioLink") {
      setLocalValue("");
      return;
    }

    if (props.structure?.type == "fileDocumentLink") {
      setLocalValue("");
      return;
    }

    setLocalValue({});
  };



  const height = 200; //resize?.h ? resize?.h * (resize?.preview || 1) : 300;




  const getFileUrl = () => {
    if (props.structure.type == "fileImageLink") {
      return localValue ?? "";
    }
    if (props.structure.type == "fileAudioLink") {
      return localValue ?? "";
    }
    if (props.structure.type == "fileDocumentLink") {
      return localValue ?? "";
    }

    return localValue?.url ?? "";
  }

  const getFileExtension = () => {
    let url = getFileUrl();
    if (!url) {
      return "";
    }
    return url.split(".").pop() ?? "";
  }

  const getFileName = () => {

    let url = getFileUrl();
    if (!url) {
      return "";
    }
    return url.split("/").pop() ?? "";
  }



  const haveValue = () => {

    switch (props.structure.type) {
      case 'fileImageLink':
      case 'fileDocumentLink':
      case 'fileAudioLink':
        return !!localValue;
      case 'fileAudioID':
      case 'fileAudio':
      case 'fileImage':
      case 'fileImageID':
      case 'fileVideo':
      case 'fileDocument':
      case 'fileDocumentID':
      case 'fileVideoID':
        return !!localValue?.url;



      default:
        return !!localValue;
    }
  }

  const isImage = props.structure.type == "fileImageLink" || props.structure.type == "fileImage" || props.structure.type == "fileImageID";
  const isAudio = props.structure.type == "fileAudioLink" || props.structure.type == "fileAudio" || props.structure.type == "fileAudioID";
  const isDocument = props.structure.type == "fileDocumentLink" || props.structure.type == "fileDocument" || props.structure.type == "fileDocumentID";
  const isVideo = props.structure.type == "fileVideo" || props.structure.type == "fileVideoID";

  if (props.onlyShow || !props.structure.editable) {


    return <>

      <DataLabel {...props} />


      {haveValue() ? <>
        <div>

          {isImage && <>

            <ImagePreview url={getFileUrl()} />

          </>}

          {isAudio && <>
            <AudioPlayer src={getFileUrl()} />

          </>}

          {isVideo && <>
            <VideoPlayer src={getFileUrl()} />

          </>}

          {isDocument && <>


            <Button variant={"outline"} className='w-full'>
              <div className='flex items-center gap-2 w-full'>
                <FileIcon /> {getFileName()}
              </div>
            </Button>


          </>}



        </div>

      </>
        : <>
          <div>
            <span className='text-gray-300 text-xs mx-2'>{Lang.key('no_data_short')}</span>
          </div>
        </>}


      <DataDescription {...props} />


    </>


  }


  const buttonTitle = () => {

    if (isImage) {
      return Lang.key('select_image')
    }
    if (isAudio) {
      return Lang.key('select_audio')
    }
    if (isDocument) {
      return Lang.key('select_document')
    }
    if (isVideo) {
      return Lang.key('select_video')
    }

    return Lang.key('select_file')

  }

  const accept = () => {
    if (isImage) {
      return "image/*";
    }
    if (isAudio) {
      return "audio/mp3";
    }
    if (isVideo) {
      return "video/*";
    }

    return "*/*";
  }

  const uploadRequest = (file: File) => {

    if (!file) {
      return;
    }


    let formData = new FormData();
    formData.append('file', file);
    if (isImage) {
      setUploading(true);
      rpc.imageUpload(formData).then((json) => {
        if (json) {
          setLocalValue(json);
        }
      }).finally(() => {
        setUploading(false);
      });
    }
    if (isAudio) {
      setUploading(true);
      rpc.audioUpload(formData).then((json) => {
        if (json) {
          setLocalValue(json);
        }
      }).finally(() => {
        setUploading(false);
      });
    }
    if (isVideo) {
      setUploading(true);
      rpc.videoUpload(formData).then((json) => {
        if (json) {
          setLocalValue(json);
        }
      }).finally(() => {
        setUploading(false);
      });
    }
    if (isDocument) {
      setUploading(true);
      rpc.documentUpload(formData).then((json) => {
        if (json) {
          setLocalValue(json);
        }
      }).finally(() => {
        setUploading(false);
      });
    }


  }

  const onUploadNewFile = () => {

    selectFile(accept()).then((file) => {

      if (file)
        uploadRequest(file);


    });

  }

  const { isMobile } = useAppConfig();
  const col = props?.structure?.col ?? 24;

  const EditGroupButtons = () => {


    return <div className='flex items-center gap-2'>

      <Button variant={"ghost"} size={'icon'} onClick={(e) => {
        e.preventDefault();
        delFile();
      }}>
        <Trash2 />
      </Button>
      <Button variant={"ghost"} onClick={(e) => {
        e.preventDefault();
        onUploadNewFile();
      }}>

        {uploading ? <>
          <Loader2 className="size-4 animate-spin" />
          {Lang.key('uploading_file_wait')}
        </> : <>
          <UploadIcon />
          {!isMobile && col > 16 ? buttonTitle() : ''}
        </>}
      </Button>
      {isAudio && <>
        <Button variant={"ghost"} onClick={(e) => {
          e.preventDefault();
          audioRecordDialogRef.current?.open({
            onSelect: (file) => {

              if (file)
                uploadRequest(file);

            }
          });
        }}>
          <BiMicrophone />
        </Button>
      </>}

      <Button variant={"ghost"} onClick={(e) => {
        e.preventDefault();
        copyTextToClipboard(getFileUrl());

      }}>
        <LinkIcon />
        {!isMobile && col > 16 ? Lang.key('copy_link') : ''}
      </Button>
    </div>
  }


  if (haveValue()) {
    return (<>
      <DataLabel {...props} />
      <div>

        {isImage && <>

          <ImagePreview url={getFileUrl()} />
          <EditGroupButtons />
        </>}

        {isAudio && <>
          <AudioPlayer src={getFileUrl()} />
          <EditGroupButtons />
        </>}

        {isVideo && <>
          <VideoPlayer src={getFileUrl()} />
          <EditGroupButtons />
        </>}

        {isDocument && <>


          <Button variant={"outline"} className='w-full'>
            <div className='flex items-center gap-2 w-full'>
              <FileIcon /> {getFileName()}
            </div>
          </Button>

          <EditGroupButtons />
        </>}



      </div>
      <DataDescription {...props} />
    </>
    );
  } else {


    return <>


      <DataLabel {...props} />


      <ButtonGroup >
        <Button variant="outline" onClick={() => {

          onUploadNewFile();


        }}>
          {uploading ? <>
            <Loader2 className="size-4 animate-spin" />
            {Lang.key('uploading_file_wait')}
          </> : <>
            <UploadIcon />
            {!isMobile && col > 16 ? buttonTitle() : ''}
          </>}

        </Button>

        {isAudio && <Button variant={"outline"} onClick={(e) => {
          e.preventDefault();
          audioRecordDialogRef.current?.open({
            onSelect: (file) => {
              if (file)
                uploadRequest(file);
            }
          });
        }}>
          <BiMicrophone />

        </Button>}
      </ButtonGroup>


      <DataDescription {...props} />


    </>


  }
};
