import React, {
  useEffect,
  useMemo,
  useState,
  useCallback,
  useRef,
} from 'react';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import Slider from '@mui/material/Slider';
import ToggleButton from '@mui/material/ToggleButton';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
import { useWavesurfer } from '@wavesurfer/react';
import RegionsPlugin from 'wavesurfer.js/dist/plugins/regions.esm.js';
import ZoomPlugin from 'wavesurfer.js/dist/plugins/zoom.esm.js';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import PauseIcon from '@mui/icons-material/Pause';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import DeleteIcon from '@mui/icons-material/Delete';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { ClipMetadata, PlaybackType } from '../../redux/types';
import { useAppSelector } from '../hooks';
import PlayStopIcon from './playStopIcon';
import PlayOverlapIcon from './playOverlapIcon';

export interface AudioTrimmerProps {
  metadata: ClipMetadata;
  onSave?: (metadata: ClipMetadata) => void;
  onDelete?: (metadata: ClipMetadata) => void;
  onMove?: (newCollection: string, metadata: ClipMetadata) => void;
}

export default function AudioTrimmer({
  metadata,
  onSave,
  onDelete,
  onMove,
}: AudioTrimmerProps) {
  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id: metadata.filename });

  // Dialog state for editing name
  const [editDialogOpen, setEditDialogOpen] = useState(false);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [dropdownOpen, setDropdownOpen] = useState(false);
  const [nameInput, setNameInput] = useState<string>(metadata.name);
  const [volumeInput, setVolumeInput] = useState<number>(metadata.volume ?? 1);
  const collectionNames = useAppSelector((state) =>
    state.collections.map((col) => col.name),
  );

  useEffect(() => {
    setNameInput(metadata.name);
  }, [metadata.name]);

  const openEditDialog = () => setEditDialogOpen(true);
  const closeEditDialog = () => setEditDialogOpen(false);

  const handleDialogSave = () => {
    if (nameInput.trim() && nameInput !== metadata.name) {
      const updated = { ...metadata, name: nameInput.trim() };
      if (onSave) onSave(updated);
    }
    closeEditDialog();
  };

  const [blobUrl, setBlobUrl] = useState<string | undefined>(undefined);
  const containerRef = useRef(null);
  // const [clipStart, setClipStart] = useState<number | undefined>(undefined);
  // const [clipEnd, setClipEnd] = useState<number | undefined>(undefined);

  const plugins = useMemo(
    () => [
      RegionsPlugin.create(),
      ZoomPlugin.create({
        scale: 0.25,
      }),
    ],
    [],
  );

  const fileBaseName =
    metadata.filename.split('\\').pop()?.split('/').pop() || 'Unknown';

  const { wavesurfer, isReady, isPlaying } = useWavesurfer({
    container: containerRef,
    height: 100,
    waveColor: '#ccb1ff',
    progressColor: '#6e44ba',
    hideScrollbar: true,
    url: blobUrl,
    plugins,
  });

  // Add this ref to always have the latest metadata
  const metadataRef = useRef(metadata);
  useEffect(() => {
    metadataRef.current = metadata;
  }, [metadata]);

  const onRegionCreated = useCallback(
    (newRegion: any) => {
      if (wavesurfer === null) return;

      const allRegions = (plugins[0] as RegionsPlugin).getRegions();
      let isNew = metadataRef.current.startTime === undefined;

      allRegions.forEach((region) => {
        if (region.id !== newRegion.id) {
          if (
            region.start === newRegion.start &&
            region.end === newRegion.end
          ) {
            newRegion.remove();
            return;
          }
          region.remove();
          isNew = !(region.start === 0 && region.end === 0);
          // console.log('Region replace:', newRegion, region);
        }
      });

      if (isNew) {
        console.log('Region created:', metadataRef.current);
        const updated = {
          ...metadataRef.current,
          startTime: newRegion.start,
          endTime: newRegion.end,
        };
        if (onSave) {
          onSave(updated);
        }
      }
    },
    [plugins, wavesurfer, onSave],
  );

  const onRegionUpdated = useCallback(
    (newRegion: any) => {
      if (wavesurfer === null) return;

      const updated = {
        ...metadataRef.current,
        startTime: newRegion.start,
        endTime: newRegion.end,
      };
      if (onSave) {
        onSave(updated);
      }
    },
    [onSave, wavesurfer],
  );

  useEffect(() => {
    const plugin = plugins[0] as RegionsPlugin;

    if (!isReady) return;
    // console.log('ready, setting up regions plugin', plugin, isReady);
    if (
      metadataRef.current.startTime !== undefined &&
      metadataRef.current.endTime !== undefined
    ) {
      // setClipStart(metadata.startTime);
      // setClipEnd(metadata.endTime);
      // console.log('Adding region from metadata:', metadata);=

      const allRegions = plugin.getRegions();
      // console.log('Existing regions:', allRegions);
      if (
        allRegions.length === 0 ||
        (allRegions.length === 1 &&
          allRegions[0].start === 0 &&
          allRegions[0].end === 0)
      ) {
        // console.log('adding region from metadata:', metadataRef.current);
        plugin.addRegion({
          start: metadataRef.current.startTime,
          end: metadataRef.current.endTime,
          color: 'rgba(132, 81, 224, 0.3)',
          drag: false,
          resize: true,
        });
      }
    } else {
      // setClipStart(0);
      // setClipEnd(wavesurfer ? wavesurfer.getDuration() : 0);
    }
  }, [isReady, plugins]);

  useEffect(() => {
    const plugin = plugins[0] as RegionsPlugin;
    plugin.unAll();
    plugin.on('region-created', onRegionCreated);
    plugin.on('region-updated', onRegionUpdated);
    plugin.enableDragSelection({
      color: 'rgba(132, 81, 224, 0.3)',
    });
  }, [onRegionCreated, onRegionUpdated, plugins]);

  useEffect(() => {
    let url: string | null = null;
    async function fetchAudio() {
      //   console.log('Loading audio buffer for file:', filename);
      const buffer = await window.audio.loadAudioBuffer(metadata.filename);
      // console.log('Received buffer:', buffer.buffer);
      if (buffer.buffer && !buffer.error) {
        const audioData = buffer.buffer
          ? new Uint8Array(buffer.buffer)
          : buffer;
        url = URL.createObjectURL(new Blob([audioData]));
        // console.log('Created blob URL:', url);
        setBlobUrl(url);
      }
    }
    fetchAudio();
    return () => {
      if (url) URL.revokeObjectURL(url);
    };
  }, [metadata.filename]);

  const onPlayPause = () => {
    if (wavesurfer === null) return;
    if (isPlaying) {
      wavesurfer.pause();
    } else {
      const allRegions = (plugins[0] as RegionsPlugin).getRegions();
      if (allRegions.length > 0) {
        wavesurfer.setVolume(metadata.volume ?? 1);
        wavesurfer.play(allRegions[0].start, allRegions[0].end);
      } else {
        wavesurfer.play();
      }
    }
  };

  const formatTime = (seconds: number) => {
    const minutes = Math.floor(seconds / 60);
    const secs = (seconds % 60).toFixed(0);
    return `${minutes}:${secs.padStart(2, '0')}`;
  };

  return (
    <div
      ref={setNodeRef}
      style={{
        transform: CSS.Transform.toString(transform),
        transition,
        position: 'relative',
        alignItems: 'stretch',
      }}
      className="shadow-[0_2px_8px_rgba(0,0,0,0.5)] m-2 rounded-lg bg-darkDrop"
    >
      <div
        // eslint-disable-next-line react/jsx-props-no-spreading
        {...attributes}
        // eslint-disable-next-line react/jsx-props-no-spreading
        {...listeners}
        style={{
          position: 'absolute',
          left: 0,
          top: 0,
          bottom: 0,
          width: '10px',
          borderRadius: '5px 0 0 5px',
          cursor: 'grab',
        }}
        className="bg-neutral-800"
      />
      {/* <div className="flex flex-col"> */}
      <div className="ml-4 mr-2 p-2">
        <div className="grid justify-items-stretch grid-cols-2">
          <div className="mb-5px flex flex-col">
            <span
              className="font-bold text-lg text-white mb-1 cursor-pointer"
              onClick={openEditDialog}
              onKeyDown={(e) => {
                if (e.key === 'Enter' || e.key === ' ') {
                  e.preventDefault();
                  openEditDialog();
                }
              }}
              title="Click to edit name"
              tabIndex={0}
              role="button"
              style={{ outline: 'none' }}
            >
              {metadata.name}
            </span>
            <span className="text-sm text-neutral-500">{fileBaseName}</span>
          </div>
          <Dialog
            open={editDialogOpen}
            onClose={closeEditDialog}
            slotProps={{
              paper: { sx: { backgroundColor: '#1a1a1a', color: 'white' } },
            }}
          >
            <DialogTitle>Edit Clip Name</DialogTitle>
            <DialogContent>
              <textarea
                autoFocus
                className="font-bold text-lg bg-transparent outline-none border-b border-plum focus:border-plumDark text-white mb-1 w-full text-center resize-y"
                value={nameInput}
                onChange={(e) => setNameInput(e.target.value)}
                rows={3}
                onFocus={(event) => event.target.select()}
                aria-label="Edit clip name"
                style={{ minHeight: '3em' }}
              />
            </DialogContent>
            <DialogActions>
              <button
                type="button"
                onClick={closeEditDialog}
                className="bg-plum hover:bg-plumDark text-white font-bold h-10 px-4 rounded-md"
              >
                Cancel
              </button>
              <button
                type="button"
                onClick={handleDialogSave}
                className="bg-plum hover:bg-plumDark text-white font-bold h-10 px-4 rounded-md"
              >
                Save
              </button>
            </DialogActions>
          </Dialog>

          <Dialog
            open={deleteDialogOpen}
            onClose={() => setDeleteDialogOpen(false)}
            slotProps={{
              paper: { sx: { backgroundColor: '#1a1a1a', color: 'white' } },
            }}
          >
            <DialogTitle>Confirm Delete</DialogTitle>
            <DialogContent>
              Are you sure you want to delete this clip?
            </DialogContent>
            <DialogActions>
              <button
                type="button"
                onClick={() => setDeleteDialogOpen(false)}
                className="bg-plum hover:bg-plumDark text-white font-bold h-10 px-4 rounded-md"
              >
                Cancel
              </button>
              <button
                type="button"
                onClick={() => {
                  setDeleteDialogOpen(false);
                  if (onDelete) onDelete(metadataRef.current);
                }}
                className="bg-plum hover:bg-plumDark text-white font-bold h-10 px-4 rounded-md"
              >
                Delete
              </button>
            </DialogActions>
          </Dialog>

          <div className="flex justify-end">
            <button
              type="button"
              className="bg-plum hover:bg-plumDark text-white font-bold h-11 w-11 rounded-md ml-1"
              onClick={onPlayPause}
            >
              {isPlaying ? <PauseIcon /> : <PlayArrowIcon />}
            </button>
            <div className="relative inline-block">
              <button
                type="button"
                className="bg-plum hover:bg-plumDark text-white font-bold h-11 w-11 rounded-md ml-1"
                onClick={() => setDropdownOpen((prev) => !prev)}
              >
                {dropdownOpen ? <ArrowDownwardIcon /> : <ArrowForwardIcon />}
              </button>
              {dropdownOpen && (
                <div className="absolute z-10 mt-2 w-40 bg-midnight rounded-md shadow-lg">
                  {collectionNames.map((name) => (
                    <button
                      key={name}
                      type="button"
                      className="block w-full text-left px-4 py-2 text-white hover:bg-plumDark"
                      onClick={() => {
                        setDropdownOpen(false);
                        if (onMove) onMove(name, metadata);
                      }}
                    >
                      {name}
                    </button>
                  ))}
                </div>
              )}
            </div>
            <button
              type="button"
              className="bg-plum hover:bg-plumDark text-white font-bold h-11 w-11 rounded-md ml-1"
              onClick={() => setDeleteDialogOpen(true)}
            >
              <DeleteIcon />
            </button>
          </div>
        </div>
        <div className="m-1 wavesurfer-scroll-container">
          <div ref={containerRef} className="wavesurfer-inner" />
        </div>
        <div className="flex justify-between mt-2">
          <span className="w-1/5 flex-none text-sm text-neutral-500 self-center">
            Clip: {formatTime(metadata.startTime ?? 0)} -{' '}
            {formatTime(metadata.endTime ?? 0)}
          </span>
          <div className="w-3/5 flex-1 flex justify-center items-center">
            <Slider
              value={volumeInput}
              min={0}
              max={1}
              step={0.01}
              onChange={(e, newValue) => setVolumeInput(newValue as number)}
              onChangeCommitted={(e, newValue) => {
                const newVolume = newValue as number;
                console.log('Volume change:', newVolume);
                if (onSave) onSave({ ...metadata, volume: newVolume });
              }}
              color="secondary"
              className="p-0 m-0"
            />
            {/* <input
              type="range"
              min={0}
              max={1}
              step={0.01}
              value={volumeInput}
              onChange={(e) => {
                const newVolume = parseFloat(e.target.value);
                setVolumeInput(newVolume);
              }}
              onDragEnd={(e) => {
                console.log('Volume change:');
                // const newVolume = parseFloat(e.target.value);
                // if (onSave) onSave({ ...metadata, volume: newVolume });
              }}
              className="mx-2 w-full accent-plum"
              aria-label="Volume slider"
            /> */}
          </div>
          <div className="w-1/5 flex justify-end text-sm text-neutral-500">
            <ToggleButtonGroup value={metadata.playbackType}>
              <ToggleButton
                value="playStop"
                color="primary"
                onClick={() => {
                  if (onSave)
                    onSave({
                      ...metadata,
                      playbackType: PlaybackType.PlayStop,
                    });
                }}
              >
                <PlayStopIcon />
              </ToggleButton>
              <ToggleButton
                value="playOverlap"
                color="primary"
                onClick={() => {
                  if (onSave)
                    onSave({
                      ...metadata,
                      playbackType: PlaybackType.PlayOverlap,
                    });
                }}
              >
                <PlayOverlapIcon />
              </ToggleButton>
            </ToggleButtonGroup>
          </div>
        </div>
      </div>
    </div>
  );
}
