'use client';

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from 'react';
import { useAuth } from '@/lib/auth/context';
import {
  addHideFromRule,
  loadHideFromRules,
  removeHideFromRule,
  type HideFromRule,
} from '@/lib/privacy-rules';
import {
  blockProfile as blockProfileLib,
  loadBlockList,
  unblockAll as unblockAllLib,
  unblockByUsername as unblockByUsernameLib,
  unblockProfile as unblockProfileLib,
  type BlockEntry,
} from '@/lib/block-list';
import type { Profile } from '@/types';

interface PrivacyContextValue {
  hideRules: HideFromRule[];
  blockList: BlockEntry[];
  addHideRule: (rule: Omit<HideFromRule, 'id' | 'created_at' | 'label'>) => void;
  removeHideRule: (id: string) => void;
  blockProfile: (profile: Profile) => void;
  unblockProfile: (blockedUserId: string) => void;
  unblockByUsername: (username: string) => boolean;
  unblockAll: () => void;
  isBlocked: (userId: string) => boolean;
  refresh: () => void;
}

const PrivacyContext = createContext<PrivacyContextValue | null>(null);

export function PrivacyProvider({ children }: { children: ReactNode }) {
  const { user } = useAuth();
  const userId = user?.id ?? null;

  const [hideRules, setHideRules] = useState<HideFromRule[]>([]);
  const [blockList, setBlockList] = useState<BlockEntry[]>([]);

  const refresh = useCallback(() => {
    setHideRules(loadHideFromRules(userId));
    setBlockList(loadBlockList(userId));
  }, [userId]);

  useEffect(() => {
    refresh();
  }, [refresh]);

  useEffect(() => {
    const onHide = () => refresh();
    const onBlock = () => refresh();
    window.addEventListener('eg-hide-rules', onHide);
    window.addEventListener('eg-block-list', onBlock);
    return () => {
      window.removeEventListener('eg-hide-rules', onHide);
      window.removeEventListener('eg-block-list', onBlock);
    };
  }, [refresh]);

  const addHideRule = useCallback(
    (rule: Omit<HideFromRule, 'id' | 'created_at' | 'label'>) => {
      const next = addHideFromRule(rule, userId);
      setHideRules(next);
    },
    [userId]
  );

  const removeHideRule = useCallback(
    (id: string) => {
      const next = removeHideFromRule(id, userId);
      setHideRules(next);
    },
    [userId]
  );

  const blockProfile = useCallback(
    (profile: Profile) => {
      const next = blockProfileLib(profile, userId);
      setBlockList(next);
    },
    [userId]
  );

  const unblockProfile = useCallback(
    (blockedUserId: string) => {
      const next = unblockProfileLib(blockedUserId, userId);
      setBlockList(next);
    },
    [userId]
  );

  const unblockByUsername = useCallback(
    (username: string) => {
      const { blocks, removed } = unblockByUsernameLib(username, userId);
      if (removed) setBlockList(blocks);
      return !!removed;
    },
    [userId]
  );

  const unblockAll = useCallback(() => {
    setBlockList(unblockAllLib(userId));
  }, [userId]);

  const isBlocked = useCallback(
    (targetId: string) => blockList.some((b) => b.id === targetId),
    [blockList]
  );

  const value = useMemo(
    () => ({
      hideRules,
      blockList,
      addHideRule,
      removeHideRule,
      blockProfile,
      unblockProfile,
      unblockByUsername,
      unblockAll,
      isBlocked,
      refresh,
    }),
    [
      hideRules,
      blockList,
      addHideRule,
      removeHideRule,
      blockProfile,
      unblockProfile,
      unblockByUsername,
      unblockAll,
      isBlocked,
      refresh,
    ]
  );

  return <PrivacyContext.Provider value={value}>{children}</PrivacyContext.Provider>;
}

export function usePrivacy() {
  const ctx = useContext(PrivacyContext);
  if (!ctx) throw new Error('usePrivacy must be used within PrivacyProvider');
  return ctx;
}