import React, { useState, useEffect } from 'react';
import { useGame } from '../../contexts/GameContext';
import { useNotification } from '../../contexts/NotificationContext';
import { useTranslation } from 'react-i18next';
import { GAME_API_URL } from '../../config';
import { GameModal } from './GameModal';
import { GameButton } from '../common/GameButton';
import { getAssetPath } from '../../utils/assetPath';
import './DialogModal.css';

interface DialogModalProps {
  npcId: string;
  npcData: any;
  onClose: () => void;
  onTrade?: () => void;
}

interface Topic {
  id: string;
  title: { [key: string]: string } | string;
  text: { [key: string]: string } | string;
}

interface Quest {
  quest_id: string;
  title: { [key: string]: string } | string;
  description: { [key: string]: string } | string;
  giver_id: string;
  objectives: any[];
  repeatable?: boolean;
  type?: 'individual' | 'global';
  // Logic for frontend state
  status?: 'available' | 'active' | 'completed' | 'can_turn_in';
}

export const DialogModal: React.FC<DialogModalProps> = ({ npcId, npcData, onClose, onTrade }) => {
  const { t } = useTranslation();
  const { token, locale, actions, inventory } = useGame();
  const { addNotification } = useNotification();
  const [dialogData, setDialogData] = useState<any>(null);
  const [currentText, setCurrentText] = useState<string>("");
  const [quests, setQuests] = useState<Quest[]>([]);
  const [viewState, setViewState] = useState<'greeting' | 'topic' | 'quest_preview'>('greeting');
  const [selectedQuest, setSelectedQuest] = useState<Quest | null>(null);

  // Fetch dialog and quests
  useEffect(() => {
    const fetchData = async () => {
      if (!token || !npcId) return;

      try {
        // 1. Fetch Dialog
        const dialogRes = await fetch(`${GAME_API_URL}/npcs/${npcId}/dialog`, {
          headers: { 'Authorization': `Bearer ${token}` }
        });
        const dialog = await dialogRes.json();
        setDialogData(dialog);

        // Initial greeting
        const greeting = getLocalized(dialog.greeting) || "Hello.";
        setCurrentText(greeting);

        // 2. Fetch Available Quests (Starts)
        const availRes = await fetch(`${GAME_API_URL}/quests/available`, {
          headers: { 'Authorization': `Bearer ${token}` }
        });
        const availableQuests = await availRes.json();

        // 3. Fetch Active Quests (Turn-ins)
        const activeRes = await fetch(`${GAME_API_URL}/quests/active`, {
          headers: { 'Authorization': `Bearer ${token}` }
        });
        const activeQuests = await activeRes.json();

        // Filter and Merge for this NPC
        const npcQuests: Quest[] = [];

        // Add available quests from this NPC
        if (Array.isArray(availableQuests)) {
          availableQuests.forEach((q: any) => {
            if (q.giver_id === npcId) {
              npcQuests.push({ ...q, status: 'available' });
            }
          });
        }

        // Add active quests from this NPC
        if (Array.isArray(activeQuests)) {
          activeQuests.forEach((q: any) => {
            if (q.giver_id === npcId && q.status === 'active') {
              npcQuests.push({ ...q, status: 'active' });
            }
          });
        }

        setQuests(npcQuests);

      } catch (e) {
        console.error("Error fetching NPC data", e);
      }
    };

    fetchData();
  }, [npcId, token, locale]);

  const getLocalized = (obj: any) => {
    if (typeof obj === 'string') return obj;
    return obj?.[locale] || obj?.['en'] || "";
  };

  const handleTopicClick = (topic: Topic) => {
    const text = getLocalized(topic.text) || "...";
    setCurrentText(text);
    setViewState('topic');
  };

  const handleQuestClick = (quest: Quest) => {
    setSelectedQuest(quest);
    const desc = getLocalized(quest.description);

    if (quest.status === 'active') {
      setCurrentText(desc + "\n\n" + t('game.dialog.questInProgress'));
    } else {
      setCurrentText(desc);
    }
    setViewState('quest_preview');
  };

  const acceptQuest = async () => {
    if (!selectedQuest) return;
    try {
      const res = await fetch(`${GAME_API_URL}/quests/accept/${selectedQuest.quest_id}`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${token}` }
      });
      if (res.ok) {
        const data = await res.json();
        // Refresh or update state
        setCurrentText(t('game.dialog.questAccepted'));
        addNotification(t('messages.questAccepted'), "success");

        if (data.quest) {
          actions.handleQuestUpdate(data.quest);
        }

        setTimeout(() => {
          setViewState('greeting');
          // Remove from available, add to active locally (simplification)
          setQuests(prev => prev.map(q => q.quest_id === selectedQuest.quest_id ? { ...q, status: 'active' } : q));
          setSelectedQuest(null);
          resetToGreeting();
        }, 1500);
      } else {
        const err = await res.json();
        addNotification(err.detail, "error");
      }
    } catch (e) {
      console.error(e);
      addNotification(t('messages.failedToAcceptQuest'), "error");
    }
  };

  // Check if player has any relevant items for the quest
  const hasRequiredItems = () => {
    if (!selectedQuest || !selectedQuest.objectives) return false;

    // If it has kill objectives, we can always "hand in" (check progress/complete)
    // unless it's ONLY item delivery.
    const hasKillObjective = selectedQuest.objectives.some((o: any) => o.type === 'kill_count');
    if (hasKillObjective) return true;

    // Check item delivery objectives
    const itemObjectives = selectedQuest.objectives.filter((o: any) => o.type === 'item_delivery');
    if (itemObjectives.length === 0) return true; // No delivery needed? Should allow.

    // Check if we have ANY of the required items in inventory
    // @ts-ignore
    return itemObjectives.some((o: any) => {
      // @ts-ignore
      const invItem = inventory.find((i: any) => i.item_id === o.target);
      return invItem && invItem.quantity > 0;
    });
  };

  const handInQuest = async () => {
    if (!selectedQuest) return;
    try {
      const res = await fetch(`${GAME_API_URL}/quests/hand_in/${selectedQuest.quest_id}`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${token}` }
      });
      const result = await res.json();

      if (res.ok) {
        if (result.quest_update) {
          actions.handleQuestUpdate(result.quest_update);
          // Update local state to reflect new progress
          setQuests(prev => prev.map(q => q.quest_id === result.quest_update.quest_id ? result.quest_update : q));
          // Also update selectedQuest so the UI reflects changes immediately if we stay on this screen
          setSelectedQuest(result.quest_update);
        }
        // Refresh game data to update inventory/stats
        actions.fetchGameData();

        if (result.is_completed) {
          addNotification(t('messages.questCompleted'), "quest");
          let msg = getLocalized(result.completion_text) || "Thank you!";
          if (result.rewards && result.rewards.length > 0) {
            msg += "\n\n" + t('game.dialog.rewards') + ":\n" + result.rewards.join('\n');
          }
          setCurrentText(msg);
          // Remove from list or mark as completed in local list
          setQuests(prev => prev.map(q => q.quest_id === selectedQuest.quest_id ? { ...q, status: 'completed' } : q));
        } else {
          addNotification(t('messages.questProgressUpdated'), "info");

          let feedback = t('game.dialog.progressUpdated');
          if (result.items_deducted && result.items_deducted.length > 0) {
            feedback += `\n\n${result.items_deducted.join('\n')}`;
          }
          // Append objective status
          if (result.quest_update && result.quest_update.objectives) {
            const objText = result.quest_update.objectives.map((o: any) => {
              const targetName = o.target_name || o.target;
              return `- ${targetName}: ${o.current}/${o.count}`;
            }).join('\n');
            feedback += `\n\n${objText}`;
          }

          setCurrentText(feedback);
        }
        // Removed setTimeout to keep user in the dialog
      } else {
        addNotification(result.detail, "error");
      }
    } catch (e) {
      console.error(e);
    }
  };

  const resetToGreeting = () => {
    if (!dialogData) return;
    const greeting = getLocalized(dialogData.greeting) || "Hello.";
    setCurrentText(greeting);
    setViewState('greeting');
    setSelectedQuest(null);
  };

  if (!dialogData) return null;

  const npcName = getLocalized(npcData?.name) || "Unknown";

  return (
    <GameModal
      title={npcName}
      onClose={onClose}
      className="dialog-modal"
    >
      <div className="npc-dialog-layout">
        <div className="npc-portrait-container">
          <img
            className="npc-portrait"
            src={npcData.image_path || npcData.image ? getAssetPath(npcData.image_path || npcData.image) : ''}
            alt={npcName}
          />
        </div>

        <div className="npc-dialog-content">
          <div className="dialogue-box">
            <p>{currentText}</p>
          </div>

          <div className="options-grid">
            {/* NPC TOPICS */}
            {viewState === 'greeting' && dialogData.topics?.map((topic: Topic) => (
              <GameButton key={topic.id} className="option-btn" size="sm" onClick={() => handleTopicClick(topic)}>
                💬 {getLocalized(topic.title)}
              </GameButton>
            ))}

            {/* QUESTS */}
            {viewState === 'greeting' && quests.map(q => (
              <GameButton
                key={q.quest_id}
                className="option-btn quest-btn"
                size="sm"
                onClick={() => handleQuestClick(q)}
                variant={q.status === 'active' ? 'warning' : q.status === 'completed' ? 'success' : 'info'}
              >
                {q.status === 'available' ? '❗' : q.status === 'completed' ? '✅' : '❓'} {getLocalized(q.title)}
              </GameButton>
            ))}

            {/* CONFIRM QUEST ACTION */}
            {viewState === 'quest_preview' && selectedQuest?.status === 'available' && (
              <div className="full-width">
                <GameButton className="option-btn action-btn" size="sm" variant="success" onClick={acceptQuest} style={{ width: '100%' }}>
                  {t('game.dialog.acceptQuest')}
                </GameButton>
              </div>
            )}

            {viewState === 'quest_preview' && selectedQuest?.status === 'active' && (
              <div className="full-width">
                <GameButton
                  className="option-btn action-btn"
                  size="sm"
                  variant="warning"
                  onClick={handInQuest}
                  style={{ width: '100%' }}
                  disabled={!hasRequiredItems()}
                >
                  {/* If it's pure kill quest, 'Complete' makes more sense than 'Hand In' */}
                  {selectedQuest.objectives?.some((o: any) => o.type === 'kill_count') && !selectedQuest.objectives?.some((o: any) => o.type === 'item_delivery')
                    ? t('game.dialog.completeQuest')
                    : t('game.dialog.handInItems')}
                </GameButton>
              </div>
            )}

            {/* TRADE - Only show in greeting */}
            {viewState === 'greeting' && npcData.trade?.enabled && (
              <GameButton className="option-btn trade-btn" size="sm" variant="success" onClick={onTrade}>
                💰 {t('game.dialog.trade')}
              </GameButton>
            )}

            {/* EXIT - Span full width */}
            {viewState === 'greeting' && (
              <GameButton className="option-btn exit-btn full-width" size="sm" variant="secondary" onClick={onClose}>
                {t('game.dialog.goodbye')}
              </GameButton>
            )}

            {/* BACK BUTTON - Moved to bottom */}
            {(viewState === 'topic' || viewState === 'quest_preview') && (
              <GameButton className="option-btn full-width" size="sm" onClick={resetToGreeting}>
                &larr; {t('game.dialog.back')}
              </GameButton>
            )}
          </div>
        </div>
      </div>
    </GameModal>
  );
};
