'use client'

import { FormEvent, MouseEvent, useState, useEffect } from 'react';
import { useParams } from 'next/navigation'
import { Album } from '@/entities/album.entity';
import { Song } from '@/entities/song.entity';
import { TimeUtils } from '@/utils/time.util';
import { createSong, deleteSong, getAlbum, getSong, updateSong, revalidateAlbum } from '@/app/actions';
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
import { Alert, Snackbar, IconButton } from '@mui/material';
import { AddCircleOutline, Delete, Edit } from '@mui/icons-material';

export default function Page() {
  const params = useParams<{ id: string }>();
  const albumId = params.id;
  const [album, setAlbum] = useState<Album>();
  const [show, setShow] = useState(false);
  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);
  const [formAlbumId, setFormAlbumId] = useState(albumId);
  const [formSongId, setFormSongId] = useState("");
  const [formSongTitle, setFormSongTitle] = useState("");
  const [formSongDuration, setFormSongDuration] = useState("");
  const [formSongTrackNumber, setFormSongTrackNumber] = useState("");
  const [formModalTitle, setFormModalTitle] = useState("Add Song");
  const [formModalButtonLabel, setFormModalButtonLabel] = useState("Add");
  const [showSnackbar, setShowSnackbar] = useState(false);
  const handleCloseSnackbar = () => setShowSnackbar(false);
  const handleOpenSnackbar = () => setShowSnackbar(true);
  const [snackbarSuccess, setSnackbarSuccess] = useState(true);
  const [snackbarMessage, setSnackbarMessage] = useState("");

  useEffect(() => {
    async function fetchAlbum(albumId: string) {
      try {
        revalidateAlbum();
        const data = await getAlbum(parseInt(albumId));
        setAlbum(data);
      } catch (error) {
        console.error(`Error getting album with id ${albumId}:`, error);
      }
    }
    fetchAlbum(albumId);
  }, [albumId]);

  const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    handleClose();

    const formData = new FormData(event.currentTarget);
    try {
      if (formData.get('id') == "") {
        await createSong(formData).then(response => {
          if (response.ok) {
            handleSnackbar(`Successfully created Song with ID ${formData.get("id")}: ${JSON.stringify(response)}`, true);
          }
          handleSnackbar(`Failed to create Song with ID ${formData.get("id")}: ${JSON.stringify(response)}`, false);
        })
        .catch(error => {handleSnackbar(`Failed to create Song with ID ${formData.get("id")}: ${JSON.stringify(error)}`, false);});
      } else {
        await updateSong(formData).then(response => {
          if (response.ok) {
            handleSnackbar(`Successfully created Song with ID ${formData.get("id")}: ${JSON.stringify(response)}`, true);
          }
          handleSnackbar(`Failed to create Song with ID ${formData.get("id")}: ${JSON.stringify(response)}`, false);
        })
        .catch(error => {handleSnackbar(`Failed to create Song with ID ${formData.get("id")}: ${JSON.stringify(error)}`, false);});
      }
      revalidateAlbum();
      const data = await getAlbum(parseInt(albumId));
      setAlbum(data);
    } catch (error) {
      handleSnackbar(`Error creating Song: ${JSON.stringify(error)}`, false);
    }
  }

  const handleCreate = async () => {
    setFormModalTitle("Add Song");
    setFormModalButtonLabel("Add");
    setFormAlbumId(albumId);
    setFormSongId("");
    setFormSongTitle("");
    setFormSongDuration("");
    setFormSongTrackNumber("");
    handleShow();
  }

  const handleEdit = async (event: MouseEvent<HTMLElement>) => {
    const songId = event.currentTarget.getAttribute('song-id');
    if (songId) {
      try {
        const data = await getSong(parseInt(songId));
        setFormModalTitle("Edit Song");
        setFormModalButtonLabel("Save");
        setFormSongId(songId);
        setFormAlbumId(albumId);
        setFormSongTitle(data.title);
        setFormSongDuration(data.duration);
        setFormSongTrackNumber(data.trackNumber);
        handleShow();
      } catch (error) {
        handleSnackbar(`Error getting song with ID ${songId}: ${JSON.stringify(error)}`, false);
      }
    } else {
      handleSnackbar(`Couldn't get ID of clicked element`, false);
      console.error("Couldn't get ID of clicked element");
    }
  }

  const handleDelete = async (event: MouseEvent<HTMLElement>) => {
    const songId = event.currentTarget.getAttribute('song-id');
    if (songId) {
      try {
        await deleteSong(parseInt(songId));
      } catch (error) {
        handleSnackbar(`Error deleting song with ID ${songId}: ${JSON.stringify(error)}`, false);
      }
      revalidateAlbum();
      const data = await getAlbum(parseInt(albumId));
      setAlbum(data);
    } else {
      handleSnackbar(`Couldn't get ID of clicked element`, false);
    }
  }

  const handleSnackbar = async (message: string, severity: boolean) => {
    setSnackbarMessage(message);
    setSnackbarSuccess(severity);
    handleOpenSnackbar();
  }

  if (!album) return <div>Loading...</div>

  return (
    <>
    <div className="container">
      <div>
        <h3>{album.title}</h3>
        <h4>{album.artist}</h4>
        <em>({album.genre})</em>
      </div>
      <IconButton aria-label="Add Album" size="large" onClick={handleCreate}>
        <AddCircleOutline fontSize="large" color="success"/>
      </IconButton>
      <table className="u-full-width">
        <thead>
          <tr>
            <th>#</th>
            <th>Title</th>
            <th>Duration</th>
            <th>Controls</th>
          </tr>
        </thead>
        <tbody>
        {album.songs.map((song: Song) => (
          <tr key={song.id}>
            <td>{song.trackNumber}</td>
            <td>{song.title}</td>
            <td>{TimeUtils.fancyTimeFormat(song.duration)}</td>
            <td>
              <IconButton aria-label="Edit Song" size="small" song-id={song.id.toString()} onClick={handleEdit}>
                <Edit fontSize="large" color="success"/>
              </IconButton>
              <IconButton aria-label="Delete Song" size="small" song-id={song.id.toString()} onClick={handleDelete}>
                <Delete fontSize="large" color="error"/>
              </IconButton>
            </td>
          </tr>
        ))}
        </tbody>
      </table>
    </div>

    <Modal
      show={show}
      onHide={handleClose}
      backdrop="static"
      keyboard={false}
    >
      <Modal.Header closeButton>
        <Modal.Title>{formModalTitle}</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <div>
          <form onSubmit={handleSubmit}>
            <input name="id" id="song-id" value={formSongId} type="hidden" />
            <input name="albumId" id="album-id" value={formAlbumId} type="hidden" />
            <div className="row">
              <div className="six columns">
                <label htmlFor="song-title">Song Title</label><input type="text" name="title" id="song-title" defaultValue={formSongTitle} />
              </div>
              <div className="six columns">
                <label htmlFor="song-duration">Duration (seconds)</label><input type="text" name="duration" id="song-duration" defaultValue={formSongDuration} />
              </div>
            </div>
            <div className="row">
              <div className="six columns">
                <label htmlFor="song-trackNumber">Track Number</label><input type="text" name="trackNumber" id="song-trackNumber" defaultValue={formSongTrackNumber} />
              </div>
            </div>
            <Button variant="primary" type="submit">{formModalButtonLabel}</Button>
          </form>
        </div>
      </Modal.Body>
      <Modal.Footer>
        <Button variant="secondary" onClick={handleClose}>
          Close
        </Button>
      </Modal.Footer>
    </Modal>

    <Snackbar open={showSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar}>
      <Alert
        onClose={handleCloseSnackbar}
        severity={snackbarSuccess ? 'success' : 'warning'}
        variant="filled"
        sx={{ width: '100%' }}
      >
        {snackbarMessage}
      </Alert>
    </Snackbar>

    </>
  );
}
