import React, { useState, useEffect, useRef } from 'react';
import DropZone from './DropZone';
import { css } from "@emotion/core";
import ScaleLoader from "react-spinners/ScaleLoader";
import logo from '../../resources/icons/96x96.png';
import { CircularProgressbar } from 'react-circular-progressbar';
import Seven from 'node-7z';

const remote = require('electron').remote;
const ffmpeg = require('fluent-ffmpeg');
const os = require('os');
const fs = require('fs');

var ffmpegPath, ffprobePath, pathTo7zip: any;

function truncate(fullStr: string, strLen: number, separator: string) {
  if (fullStr.length <= strLen) return fullStr;

  separator = separator || '...';

  var sepLen = separator.length,
      charsToShow = strLen - sepLen,
      frontChars = Math.ceil(charsToShow/2),
      backChars = Math.floor(charsToShow/2);

  return fullStr.substr(0, frontChars) +
         separator +
         fullStr.substr(fullStr.length - backChars);
};

const app_path = remote.app.getAppPath().replace('/app.asar','')

if( process.env.NODE_ENV === 'development' ) {
  ffmpegPath = __dirname + '/../node_modules/ffmpeg-static/ffmpeg';
  ffprobePath = __dirname + '/../node_modules/ffprobe-static/bin/darwin/x64/ffprobe';
  pathTo7zip = __dirname + '/../node_modules/7zip-bin/mac/7za';
} else {
  ffprobePath = app_path + '/resources/ffprobe';
  ffmpegPath = app_path + '/resources/ffmpeg';
  pathTo7zip = app_path + '/resources/7za';
}

// console.log(app_path);
// console.log(ffmpegPath);
// console.log(ffprobePath);
// console.log(pathTo7zip);

ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg.setFfprobePath(ffprobePath);

type videoDetails = {
  id: number;
  path: string;
  filename: string;
  newFilename: string
  codec: string;
  duration: number;
  fps: string;
  bit_rate: string;
  resolutionX: number;
  resolutionY: number;
  progress: number;
  error: string;
};

const getFfprobe = (filePath: string, callback: any) => {
  ffmpeg.ffprobe(filePath, function(err, metadata) {
    if( err ) {
      return callback(false);
    }
    return callback(metadata);
  });
}

export default function Home(): JSX.Element {
  const [loading, setLoading] = useState<boolean>(true);
  const [loadingFiles, setLoadingFiles] = useState<boolean>(false);
  const [myfiles, setMyFiles] = useState<videoDetails[]>([]);
  const myfilesRef = useRef(myfiles);

  const setMyfilesRef = (newFiles) => {
    myfilesRef.current = newFiles;
    setMyFiles(newFiles);
  }

  const filenameCount = 50;
  useEffect(
    () => {
      setTimeout(
        () => {
          setLoading(false);
        },
        1000
      )
    },
    []
  )

  const onDrop = (transferedFiles: any) => {
    // pętla -> ffprobe -> ffmpeg - avi -> next
    setMyfilesRef([]);
    setLoadingFiles(true);
    console.log(transferedFiles);
    convertSingleFile(transferedFiles, function(res) {
      setLoadingFiles(false);
    });
  };

  const getFPS = (fpsText: any) => {
    try {
      const thisFPS = fpsText.split('/');
      const calcFPS = Math.round(parseInt(thisFPS[0]) / parseInt(thisFPS[1]));
      return calcFPS;
    } catch(e) {
      return fpsText;
    }

  }

  const convertSingleFile = (files: any, callback: any) => {
    var i = 0;
    (
      function convert() {
        if( i >= files.length ) {
          return callback(true)
        }
        try {
          getFfprobe(files[i].path, function(result: any) {
            console.log(result);
            let baseFilename = files[i].path.replace(/^.*[\\\/]/, '');
            if( result === false ) {
              let newItem = {
                id: i,
                path: files[i].path.substring(0, files[i].path.lastIndexOf("/")),
                filename: baseFilename,
                newFilename: '',
                codec: '?',
                duration: 0,
                fps: '',
                bit_rate: 0,
                resolutionX: 0,
                resolutionY: 0,
                progress: 0,
                error: 'Niepoprawny plik',
              };
              const newmyfiles = [...myfilesRef.current, newItem];
              setMyfilesRef(newmyfiles);
              i++;
              convert();
              return false;
            }

            // let videoC = 'rawvideo';
            // let outputOptions: string[] = ['-pix_fmt uyvy422'];
            // // console.log(result);
            // if( result.streams[0].codec_name === 'rawvideo' && result.format.hasOwnProperty('tags') ) {
            //   if (result.streams[0].pix_fmt === 'bgr24') {
            //     videoC = 'copy';
            //   }
            // }


            let videoC = 'rawvideo';
            let outputOptions: string[] = ['-pix_fmt uyvy422'];
            console.log(result);
            //console.log(result.format.tags);
            if (result.streams.length > 0) {
              if (result.streams[0].codec_name === 'rawvideo' && result.streams[0].pix_fmt === 'bgr24') {
                videoC = 'copy';
                outputOptions = [];
              }
            }

            // if (result.format.hasOwnProperty('tags')) {
            //   if( result.format.tags.hasOwnProperty('encoder') ) {
            //     if( result.format.tags.encoder.indexOf('Adobe After Effects') !== -1 ) {
            //       if( result.streams[0].codec_name === 'rawvideo' ) {
            //         if (result.streams[0].pix_fmt === 'bgr24') {
            //           videoC = 'copy';
            //         }
            //       }
            //     }
            //   }
            // }


            let newFilename = baseFilename.split('.')
            newFilename.splice(-1);
            let zipFilename = newFilename.join('.') + '_mac_bt.7z';
            newFilename = newFilename.join('.') + '_mac_bt.avi';
            let fps = getFPS(result.streams[0].r_frame_rate);

            let newItem = {
              id: i,
              path: files[i].path.substring(0, files[i].path.lastIndexOf("/")),
              filename: baseFilename,
              newFilename: zipFilename,
              codec: result.streams[0].codec_long_name,
              duration: Math.round(result.format.duration),
              fps: fps,
              bit_rate: result.streams[0].bit_rate,
              resolutionX: result.streams[0].width,
              resolutionY: result.streams[0].height,
              progress: 0,
              error: '',
            };

            const newmyfiles = [...myfilesRef.current, newItem];

            setMyfilesRef(newmyfiles);
            // best codec = msmpeg4v2
            ffmpeg(files[i].path)
              .videoCodec(videoC)
              // .size('1536x80')
              // .videoCodec('rawvideo')
              .outputOptions(outputOptions)
              //.size('1000x50')
              //.noAudio()
              //.outputOptions('-pix_fmt bgr24')
              .on('end', function() {
                const yy = myfilesRef.current.map((file) => file.id === i ? {
                  ...file,
                  progress: 100,
                } : file);
                // files[i].path.substring(0, files[i].path.lastIndexOf("\\")) + '\\' + newFilename
                // console.log('avi input = ' + yy[0].path + '\\' + newFilename);
                // console.log('7z output = ' + yy[0].path + '\\' + 'File.7z');
                const myStream = Seven.add(yy[0].path + '/' + zipFilename, yy[0].path + '/' + newFilename, {
                  $bin: pathTo7zip,
                  $progress: true
                });

                myStream.on('error', (err: any) => console.log(err));
                myStream.on('progress', function (progress: any) {
                  const yy = myfilesRef.current.map((file) => file.id === i ? {
                    ...file,
                    progress: Math.round(progress.percent) > 100 ? 100 : Math.round(50 + (progress.percent/2)),
                  } : file);
                  setMyfilesRef(yy);
                })
                myStream.on('end', () => {
                  fs.unlink(yy[0].path + '/' + newFilename, (err) => {
                    setMyfilesRef(yy);
                    i++;
                    convert();
                  })
                });
              })
              .on('progress', function(progress: any) {
                const yy = myfilesRef.current.map((file) => file.id === i ? {
                  ...file,
                  progress: Math.round(progress.percent) > 100 ? 50 : Math.round(progress.percent/2),
                } : file);
                setMyfilesRef(yy);
              })
              .on('error', function(err: any) {
                console.log(err);
              })
              .format('avi')
              .save(files[i].path.substring(0, files[i].path.lastIndexOf("/")) + '/' + newFilename);
          });
        } catch(e) {
          console.log(e);
          i++;
          convert();
        }
      }
    )();
  }

  if( loading ) {
    return(
      <div style={{display:'flex',justifyContent:'center',alignItems:'center',width:'100%',flexDirection:'column'}}>
        <img src={logo} alt="" />
        <ScaleLoader
          color={"#1976d2"}
          loading={true}
        />
      </div>
    )
  }

  return (
    <div style={{display:'flex',flex:1,flexDirection:'column'}}>
      <DropZone loadingFiles={loadingFiles} myOnDrop={onDrop} />
      <div style={{height: 'auto',overflow:'auto'}}>
        {myfiles.map(
          (file, i) => <div key={file.filename + i} style={{display: 'flex',flexDirection:'row',background: i%2 === 0 ? "#eee" : '#fff',padding: 2,borderBottom:'1px solid #ccc'}}>
            <div style={{padding:'5px 10px',fontSize:13,fontWeight:'bold',display:'flex',justifyContent:'space-around',flexDirection:'column',flex:1}}>
              <div style={{marginBottom:10}} title={file.filename}>
                <div style={{fontSize:11,textAlign:'center',fontWeight:'lighter'}}>plik wejściowy</div>
                <div style={{fontSize:13,textAlign:'center'}}>{truncate(file.filename, filenameCount, '...')}</div>
              </div>
              <div title={file.newFilename}>
                <div style={{fontSize:11,textAlign:'center',fontWeight:'lighter'}}>plik wyjściowy</div>
                <div style={{fontSize:13,textAlign:'center'}}>{truncate(file.newFilename, filenameCount, '...')}</div>
              </div>
            </div>
            <div style={{padding:'5px 10px',display:'flex',flexDirection:'column',flex:'0 1 150px',paddingTop:9}}>
              <div style={{flex:1,textAlign:'center'}}><i className="fas fa-clock"></i> <b>{file.duration}sec</b></div>
              <div style={{flex:1,textAlign:'center'}}><i className="fas fa-desktop"></i> <b>{file.resolutionX} x {file.resolutionY} px</b></div>
              <div style={{flex:1,textAlign:'center'}}>kl/s: <b>{file.fps}</b></div>
            </div>
            <div style={{padding:0,flex:'0 1 60px'}}>
              { file.error
                ? <div style={{fontSize:12,textAlign:'center',paddingTop:15,color:'red',paddingRight:10}}>{file.error}</div>
                : <CircularProgressbar value={file.progress} text={`${file.progress}%`} />
              }

            </div>
          </div>
        )}
      </div>
    </div>
  );
}
