import { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
  createMyMixdown,
  enqueueMyMixdown,
  addWatchedMixdown,
  removeWatchedMixdown,
  fetchJamTrack,
} from '../store/features/jamTrackSlice';
import { SAMPLE_RATE } from '../helpers/jamTracks';
import { createAlert } from '../helpers/rest';
import { useAuth } from '../context/UserAuth';
import { useAppData } from '../context/AppDataContext';

export const useJamTrack = () => {
  const { appData } = useAppData();
  const jamTrack = useSelector(state => state.jamTrack.jamTrack);
  const jamTrackLoadingStatus = useSelector(state => state.jamTrack.jamTrackLoadingStatus);

  const mixdowns = useSelector(state => state.jamTrack.mixdowns);
  const newMixdownLoadingStatus = useSelector(state => state.jamTrack.newMixdownLoadingStatus);

  const awaitingMixdown = useSelector(state => state.jamTrack.awaitingMixdown);
  const enqueuedMixdown = useSelector(state => state.jamTrack.enqueuedMixdown);
  const enqueuedMixdowns = useSelector(state => state.jamTrack.enqueuedMixdowns);
  const watchedMixdowns = useSelector(state => state.jamTrack.watchedMixdowns);

  const { currentUser } = useAuth();
  const dispatch = useDispatch();

  const [showQueueTime, setShowQueueTime] = useState(false);
  const [enqueueTimeMessage, setEnqueueTimeMessage] = useState('');
  const [showRetryConfirm, setShowRetryConfirm] = useState(false);
  const [retryConfirmMessage, setRetryConfirmMessage] = useState('');


  useEffect(() => {
    if (!jamTrack) {
      return
    }
    //reset watched mixdowns on unload
    return () => {
      watchedMixdowns.forEach(subscription => {
        window.JK.SubscriptionUtils.unsubscribe(subscription.type, subscription.id);
      });
    };
  }, [jamTrack]);

  const loadJamTrack = (id) => {
    dispatch(fetchJamTrack({ id }));
  };

  const createMixdown = (options) => {
    //console.log('*_DEBUG_ createNewMixdown', options);
    dispatch(createMyMixdown(options));
  };

  const enqueueMixdownForSigning = (options) => {
    //console.log('*_DEBUG_ enqueueMixdownForSigning', options);
    dispatch(enqueueMyMixdown(options));
  };

  const showEstimatedTime = () => {
    //console.log('*_DEBUG_ showEstimatedTime enqueuedMixdown', enqueuedMixdown);
    if(!enqueuedMixdown || !enqueuedMixdown.packages || enqueuedMixdown.packages.length === 0) {
      return;
    }
    const time = enqueuedMixdown.packages[0].queue_time;

    if (time === 0) {
      setEnqueueTimeMessage('Your custom mix will take about 1 minute to be created.');
    } else {
      const guess = Math.ceil(time / 60.0);
      if (guess === 1) {
        setEnqueueTimeMessage('Your custom mix will take about 1 minute to be created.');
      } else {
        setEnqueueTimeMessage(`Your custom mix will take about ${guess} minutes to be created.`);
      }
    }
    setShowQueueTime(true);
  };

  const manageWatchedMixdowns = () => {
    console.log('Managing watched mixdowns');
    mixdowns.forEach(mixdown => {
      if (mixdown.oggPackage) {
        if (mixdown.oggPackage.signing_state === 'SIGNED') {
          console.log('unsubscribing to mixdown', mixdown);
          unsubscribe(mixdown.oggPackage);
        } else {
          console.log('subscribing to mixdown', mixdown);
          subscribe(mixdown.oggPackage);
        }
      }
    });
  };

  const subscriptionKey = mixdown_package => {
    return `mixdown-${mixdown_package.id}`;
  };

  const subscribe = mixdown_package => {
    const key = subscriptionKey(mixdown_package);
    console.log('watchedMixdowns', watchedMixdowns);
    if (!watchedMixdowns[key]) {
      window.JK.SubscriptionUtils.subscribe('mixdown', mixdown_package.id).on(
        window.JK.EVENTS.SUBSCRIBE_NOTIFICATION,
        onMixdownSubscriptionEvent
      );
      dispatch(addWatchedMixdown({ type: 'mixdown', id: mixdown_package.id }));
    }
  };

  const unsubscribe = mixdown_package => {
    const key = subscriptionKey(mixdown_package);
    if (watchedMixdowns[key]) {
      window.JK.SubscriptionUtils.unsubscribe('mixdown', mixdown_package.id);
      dispatch(removeWatchedMixdown({ type: 'mixdown', id: mixdown_package.id }));
    }
  };

  const onMixdownSubscriptionEvent = (e, data) => {
    console.log("JamTrackStore: subscription notification received: type:" + data.type, data)
    const mixdown_package_id = data.id;
    mixdowns.forEach(mixdown => {
      const mixdown_package = mixdown.packages.find(p => p.id === mixdown_package_id);
      if (mixdown_package) {
        mixdown_package.signing_state = data.body.signing_state
        mixdown_package.packaging_steps = data.body.packaging_steps
        mixdown_package.current_packaging_step = data.body.current_packaging_step
        console.log("updated package with subscription notification event")

        if (mixdown_package.signing_state === 'SIGNING_TIMEOUT' || mixdown_package.signing_state === 'QUEUED_TIMEOUT' || mixdown_package.signing_state === 'QUIET_TIMEOUT' || mixdown_package.signing_state === 'ERROR') {
          reportError(mixdown)
        }
      }
    })
  }

  const reportError = (mixdown) => {
    const enqueued = enqueuedMixdowns[mixdown?.id]
    if (!enqueued || enqueued.marked) {
      return
    }
    enqueued.marked = true
    const data = {
      value: 1,
      user_id: currentUser.id,
      user_name: currentUser.name,
      result: `signing state: ${mixdown.oggPackage?.signing_state}, client state: ${mixdown.client_state}`,
      mixdown: mixdown.id,
      package: mixdown.oggPackage?.id,
      detail: mixdown.oggPackage?.error_reason
    }
    createAlert(`Mixdown Sync failed for ${currentUser.name}`, data)
  }

  const getMasterAudioUrl = () => {
    console.log('_DEBUG_ useJamTrack getMasterAudioUrl', jamTrack);
    const masterTrack = jamTrack.tracks.find(track => track.track_type === 'Master');
    if (masterTrack) {
      const audioUrl = masterTrack.preview_mp3_url;
      return audioUrl;
    }
  };

  const getMixdownAudioUrl = async (mixdownId) => {
    const activeMix = jamTrack.mixdowns.find(mix => mix.id === mixdownId);
    // const fp = await fpPromise;
    // const result = await fp.get();
    const audioUrl =
      process.env.REACT_APP_API_BASE_URL +
      `/mixdowns/${activeMix.id}/download.mp3?file_type=mp3&sample_rate=48&mark=${appData?.visitorId}`;
    return audioUrl;
  };

  const getStemAudioUrl = async (stemId) => {
    const activeTrack = jamTrack.tracks.find(track => track.id === stemId);
    // const fp = await fpPromise;
    // const result = await fp.get();
    const audioUrl =
      process.env.REACT_APP_API_BASE_URL +
      `/jamtracks/${jamTrack.id}/stems/${activeTrack.id}/download.mp3?file_type=mp3&mark=${appData?.visitorId}`;
    return audioUrl;
  };

  const confirmRetryMixdownSigning = () => {

    // SIGNED - the package is ready to be downloaded
    // ERROR - the package was built unsuccessfully
    // SIGNING_TIMEOUT - the package was kicked off to be signed, but it seems to have hung
    // SIGNING - the package is currently signing
    // QUEUED_TIMEOUT - the package signing job (JamTrackBuilder) was queued, but never executed
    // QUEUED - the package is queued to sign
    // QUIET - the jam_track_right exists, but no job has been kicked off; a job needs to be enqueued

    console.log('confirmRetryMixdownSigning', jamTrack);

    if(!jamTrack.mp3Package) {
      setRetryConfirmMessage('Custom mix never got created. Retry?');
      showRetryConfirm(true);
    }else{
      switch (jamTrack.mp3Package.signing_state) {
        case 'QUIET_TIMEOUT':
          setRetryConfirmMessage('Custom mix never got created. Retry?');
          setShowRetryConfirm(true);
          break;
        case 'QUEUED_TIMEOUT':
          setRetryConfirmMessage('Custom mix was never built. Retry?');
          setShowRetryConfirm(true);
          break;
        case 'SIGNING_TIMEOUT':
          setRetryConfirmMessage('Custom mix took long to build. Retry?');
          setShowRetryConfirm(true);
          break;
        case 'ERROR':
          setRetryConfirmMessage('Custom mix failed to build. Retry?');
          setShowRetryConfirm(true);
          break;
        case 'QUIET':
          setRetryConfirmMessage('Custom mix never got created. Retry?');
          setShowRetryConfirm(true);
          break;
        default:
          break;
      }
    }
   
  }

  const trackName = track => {
    if (track.track_type === 'Track' || track.track_type === 'Click' || track.track_type === 'Master') {
      if (track.track_type === 'Click') {
        return 'Clicktrack';
      } else if (track.track_type === 'Master') {
        return 'Master Mix';
      } else if (track.instrument) {
        const instrumentDescription = track.instrument.description;
        const instrumentDescriptionParts = instrumentDescription.split(' ');
        let part = '';
        // if (track.part && track.part !== instrumentDescription) {
        if (track.part && !instrumentDescriptionParts.includes(track.part)) {
          part = `(${track.part})`;
        }
        return `${instrumentDescription} ${part}`;
      }
    }
  };

  return { loadJamTrack, jamTrack, jamTrackLoadingStatus, mixdowns, newMixdownLoadingStatus, awaitingMixdown, enqueuedMixdown, enqueuedMixdowns, watchedMixdowns, showQueueTime, setShowQueueTime, enqueueTimeMessage, createMixdown, getMasterAudioUrl, getMixdownAudioUrl, confirmRetryMixdownSigning, retryConfirmMessage, showRetryConfirm, setShowRetryConfirm, enqueueMixdownForSigning, manageWatchedMixdowns, showEstimatedTime, getStemAudioUrl, trackName };
}

export default useJamTrack




