import React from 'react';
import {
  DndContext,
  closestCenter,
  PointerSensor,
  useSensor,
  useSensors,
} from '@dnd-kit/core';
import {
  arrayMove,
  SortableContext,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
import AudioTrimmer from './AudioTrimer';
import { ClipMetadata } from '../../redux/types';
import { useAppDispatch, useAppSelector } from '../hooks';

export interface ClipListProps {
  collection: string;
}

export default function ClipList({ collection }: ClipListProps) {
  const metadata = useAppSelector(
    (state) =>
      state.collections.find((col) => col.name === collection) || { clips: [] },
  );
  const dispatch = useAppDispatch();

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
  );

  const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
    event.preventDefault();
    console.log('Files dropped:', event.dataTransfer.files);
    const files = Array.from(event.dataTransfer.files).filter((file) =>
      file.type.startsWith('audio/'),
    );
    if (files.length > 0) {
      const formData = new FormData();
      files.forEach((file) => formData.append('files', file));

      // todo send the file to the backend and add to the collection

      // fetch('http://localhost:5010/file/upload', {
      //   method: 'POST',
      //   body: formData,
      // })
      //   .then((res) => res.json())
      //   .catch((err) => console.error('Error uploading files:', err));
      // Implement your onDrop logic here
      // onDrop(files, selectedCollection);
    }
  };

  const handleDragOver = (event: React.DragEvent<HTMLDivElement>) => {
    event.preventDefault();
  };

  async function handleDragEnd(event: any) {
    const { active, over } = event;
    if (active.id !== over?.id) {
      const oldIndex = metadata.clips.findIndex(
        (item) => item.filename === active.id,
      );
      const newIndex = metadata.clips.findIndex(
        (item) => item.filename === over.id,
      );
      const newMetadata = {
        ...metadata,
        clips: arrayMove(metadata.clips, oldIndex, newIndex),
      };
      console.log('New order:', newMetadata);
      dispatch({
        type: 'metadata/setCollections',
        payload: { collection, newMetadata },
      });
      try {
        const response = await fetch(
          'http://localhost:5010/meta/collection/clips/reorder',
          {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              name: collection,
              clips: newMetadata.clips,
            }),
          },
        );
        const data = await response.json();
        console.log('handle reorder return:', data.collections);
        dispatch({ type: 'metadata/setAllData', payload: data });
      } catch (error) {
        console.error('Error saving new clip order:', error);
      }
      // setMetadata(newMetadata);
    }
  }

  async function handleDelete(meta: ClipMetadata) {
    dispatch({
      type: 'metadata/deleteClip',
      payload: { collection, clip: meta },
    });
    fetch('http://localhost:5010/meta/collection/clips/remove', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        name: collection,
        clip: meta,
      }),
    })
      .then((res) => res.json())
      .catch((err) => console.error('Error deleting clip:', err));
    console.log('Deleting clip:', meta);
  }

  async function handleClipMove(targetCollection: string, meta: ClipMetadata) {
    console.log('Moving clip:', meta, 'to collection:', targetCollection);
    dispatch({
      type: 'metadata/moveClip',
      payload: { sourceCollection: collection, targetCollection, clip: meta },
    });
    fetch('http://localhost:5010/meta/collection/clips/move', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        sourceCollection: collection,
        targetCollection,
        clip: meta,
      }),
    })
      .then((res) => res.json())
      .catch((err) => console.error('Error moving clip:', err));
  }

  async function handleClipSave(meta: ClipMetadata) {
    try {
      dispatch({
        type: 'metadata/editClip',
        payload: { collection, clip: meta },
      });
      const response = await fetch(
        'http://localhost:5010/meta/collection/clips/edit',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            name: collection,
            clip: meta,
          }),
        },
      );
      await response.json();
      // console.log('handle clip save return:', data.collections);
      dispatch({
        type: 'metadata/editClip',
        payload: { collection, clip: meta },
      });
    } catch (error) {
      console.error('Error saving clip metadata:', error);
    }
  }

  return (
    <div
      className="min-h-full flex flex-col justify-start bg-midnight text-offwhite"
      onDrop={handleDrop}
      onDragOver={handleDragOver}
    >
      <DndContext
        sensors={sensors}
        collisionDetection={closestCenter}
        // eslint-disable-next-line react/jsx-no-bind
        onDragEnd={handleDragEnd}
        modifiers={[restrictToVerticalAxis]}
      >
        <SortableContext
          items={metadata.clips.map((item) => item.filename)}
          strategy={verticalListSortingStrategy}
        >
          {metadata.clips.map((trimmer, idx) => (
            <React.Fragment key={trimmer.filename}>
              <AudioTrimmer
                metadata={trimmer}
                onSave={handleClipSave}
                onDelete={handleDelete}
                onMove={handleClipMove}
              />
              {(idx + 1) % 10 === 0 && idx !== metadata.clips.length - 1 && (
                <div className="my-4 border-t border-gray-500">
                  <p className="text-center text-sm text-gray-400">
                    -- Page {Math.ceil((idx + 1) / 10) + 1} --
                  </p>
                </div>
              )}
            </React.Fragment>
          ))}
          {/* {metadata.map((trimmer) => (
            <AudioTrimmer
              key={trimmer.filename}
              filename={trimmer.filename}
              onSave={handleClipSave}
            />
          ))} */}
        </SortableContext>
      </DndContext>
    </div>
    // <div className="min-h-screen flex flex-col justify-center bg-midnight text-offwhite">
    //   <AudioTrimmer
    //     title="audio_capture_20251206_123108.wav"
    //     filePath="C:\\Users\\mickl\\Music\\clips\\original\\audio_capture_20250118_000351.wav"
    //     // section="Section 1"
    //   />
    //   <AudioTrimmer
    //     title="audio_capture_20251206_123108.wav"
    //     filePath="C:\\Users\\mickl\\Music\\clips\\original\\audio_capture_20250118_000351.wav"
    //     // section="Section 1"
    //   />
    //   <AudioTrimmer
    //     title="audio_capture_20251206_123108.wav"
    //     filePath="C:\\Users\\mickl\\Music\\clips\\original\\audio_capture_20250118_000351.wav"
    //     // section="Section 1"
    //   />
    // </div>
  );
}
