import { useCallback, useMemo, useState } from 'react';
import { useCurrentViewContext } from 'context/useCurrentView';
import { useStore, store, Notes } from 'lib/store';
import ErrorBoundary from 'components/misc/ErrorBoundary';
import NoteSumList from 'components/note/NoteSumList';
import FindOrCreateInput from 'components/note/NoteNewInput';
import { defaultNote, Note } from 'types/model';
import { dateCompare, getStrDate, regDateStr, joinPath } from 'utils/helper';
import { refreshFile } from 'editor/hooks/useRefresh';
import HeatMap from './HeatMap';

export default function Chronicle() {
  
  const initDir = useStore((state) => state.initDir) || 'md';
  const currentView = useCurrentViewContext();
  const dispatch = currentView.dispatch;

  const onNewDailyNote = useCallback(async (date: string) => {
    if (!initDir || !regDateStr.test(date)) return;
    const noteId = joinPath(initDir, 'daily', `${date}.md`);
    const note = await refreshFile(noteId);
    if (!note) {
      const newNote: Note = {
        ...defaultNote,
        id: noteId, 
        title: date, 
        file_path: noteId,
        is_daily: true, 
      };
      store.getState().upsertNote(newNote);
      const dailyDir = joinPath(initDir, 'daily');
      const newDailyDir: Note = {
        ...defaultNote,
        id: dailyDir, 
        title: 'daily', 
        file_path: dailyDir,
        is_dir: true, 
      };
      store.getState().upsertTree(initDir, [newDailyDir]); 
      store.getState().upsertTree(dailyDir, [newNote]); 
      const cNote: Notes = {};
      cNote[noteId] = newNote;
      store.getState().setCurrentNote(cNote);
    }
    await refreshFile(noteId);
    dispatch({view: 'md', params: { noteId }});
  }, [dispatch, initDir]);

  const today = getStrDate((new Date()).toString());

  return (
    <ErrorBoundary>
      <div className="flex flex-1 flex-col flex-shrink-0 py-6 px-12 w-full mx-auto bg-white dark:bg-black dark:text-gray-200 overlfow-y-auto">
        <div className="flex justify-center my-6">
          {initDir ? (
            <FindOrCreateInput
              className="w-full bg-white rounded shadow-popover dark:bg-gray-800"
            />
          ) : null}
        </div>
        <div className="my-1 p-1 rounded text-center">
          <button onClick={() => dispatch({view: 'journal'})} className="link text-2xl">
            Journals
          </button>
          <button className="link w-full mt-2" onClick={() => onNewDailyNote(today)}>
            Today : {today}
          </button>
        </div>
        <HeatMapAndList onNewDailyNote={onNewDailyNote} />
      </div>
    </ErrorBoundary>
  );
}

type Props = {
  onNewDailyNote: (date: string) => void;
  className?: string;
};

function HeatMapAndList(props: Props) {
  const { onNewDailyNote } = props
  // console.log("heat loaded?");

  const notes = useStore((state) => state.notes);

  const noteList: Note[] = useMemo(() => {
    const noteList: Note[] = Object.values(notes) || [];
    return noteList;
  }, [notes]);
  
  const sortedNotes = useMemo(() => {
    const myNotes = noteList.filter(n => !n.is_daily && !n.is_dir);
    myNotes.sort((n1, n2) => dateCompare(n2.created_at, n1.created_at));
    return myNotes;
  }, [noteList])

  const [firstDay, setFirstDay] = useState<string>('');
  const showDailyNote = useCallback((date: string) => {
    setFirstDay(date);
  }, []);

  const dateArr = useMemo(() => {
    const upDates = sortedNotes.map(n => getStrDate(n.created_at));
    const dateSet = new Set(upDates);
    const dates = Array.from(dateSet);
    const first = firstDay ? [firstDay] : [];
    const dateList = [...first, ...dates];
    return dateList;
  }, [firstDay, sortedNotes])

  // get notes on a date
  const getDayNotes = useCallback(
    (date: string) => sortedNotes.filter(n => getStrDate(n.created_at) === date), 
    [sortedNotes]
  );
  
  return (
    <>
      <HeatMap noteList={noteList} onClickCell={showDailyNote} />
      <div className="overlfow-auto">
        {dateArr.slice(0,42).map((d, idx) => (
          <NoteSumList
            key={`${d}-${idx}`}
            anchor={d}
            notes={getDayNotes(d)}
            isDate={true}
            onClick={onNewDailyNote} 
          />
        ))}
      </div>
    </>
  );
}
