import { useState, useEffect, useCallback } from 'react';

export interface DiffComment {
  id: string;
  body: string;
  createdAt: number;
  updatedAt: number;
}

export interface DiffCommentTarget {
  filePath: string;
  side: 'old' | 'new';
  lineNumber: number;
}

function loadFromStorage(key: string): Map<string, DiffComment[]> {
  try {
    const raw = localStorage.getItem(key);
    if (!raw) return new Map();
    const parsed = JSON.parse(raw);
    return new Map(Object.entries(parsed));
  } catch {
    return new Map();
  }
}

function saveToStorage(key: string, map: Map<string, DiffComment[]>) {
  const obj: Record<string, DiffComment[]> = {};
  for (const [k, v] of map) obj[k] = v;
  localStorage.setItem(key, JSON.stringify(obj));
}

export function useDiffComments(sessionId: string, mode: string) {
  const storageKey = `boocode.diff.comments.${sessionId}.${mode}`;
  const [comments, setComments] = useState<Map<string, DiffComment[]>>(() =>
    loadFromStorage(storageKey)
  );

  useEffect(() => {
    saveToStorage(storageKey, comments);
  }, [storageKey, comments]);

  const addComment = useCallback(
    (key: string, comment: DiffComment) => {
      setComments((prev) => {
        const next = new Map(prev);
        const list = next.get(key) ?? [];
        next.set(key, [...list, comment]);
        return next;
      });
    },
    []
  );

  const updateComment = useCallback(
    (key: string, id: string, body: string) => {
      setComments((prev) => {
        const next = new Map(prev);
        const list = next.get(key);
        if (!list) return prev;
        next.set(
          key,
          list.map((c) =>
            c.id === id ? { ...c, body, updatedAt: Date.now() } : c
          )
        );
        return next;
      });
    },
    []
  );

  const deleteComment = useCallback(
    (key: string, id: string) => {
      setComments((prev) => {
        const next = new Map(prev);
        const list = next.get(key);
        if (!list) return prev;
        const filtered = list.filter((c) => c.id !== id);
        if (filtered.length === 0) {
          next.delete(key);
        } else {
          next.set(key, filtered);
        }
        return next;
      });
    },
    []
  );

  return { comments, addComment, updateComment, deleteComment };
}
