"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { Pill, Volume2 } from "lucide-react";

interface Medication {
  id: string;
  drugName: string;
  dosage: string;
  timing: string;
}

interface MedicationAlertProps {
  patientId: string;
  medications: Medication[];
}

function getTimingCategory(timing: string): "morning" | "afternoon" | "evening" | "other" {
  const lower = timing.toLowerCase();
  const morningKeywords = [
    "morning", "am", "matin", "sobh", "صباح", "breakfast", "petit déjeuner",
  ];
  const afternoonKeywords = [
    "afternoon", "noon", "midday", "lunch", "après-midi", "zohr", "ظهر",
  ];
  const eveningKeywords = [
    "night", "pm", "evening", "soir", "lil", "ليل", "dinner", "dîner", "bedtime", "coucher",
  ];

  if (morningKeywords.some((k) => lower.includes(k))) return "morning";
  if (afternoonKeywords.some((k) => lower.includes(k))) return "afternoon";
  if (eveningKeywords.some((k) => lower.includes(k))) return "evening";
  return "other";
}

function getCurrentTimeCategory(): "morning" | "afternoon" | "evening" | "other" {
  const hour = new Date().getHours();
  if (hour >= 6 && hour < 12) return "morning";
  if (hour >= 12 && hour < 17) return "afternoon";
  if (hour >= 17 && hour < 22) return "evening";
  return "other";
}

function getStorageKey(): string {
  const date = new Date().toISOString().split("T")[0];
  return `rememberme_meds_${date}`;
}

function getTakenMedIds(): string[] {
  if (typeof window === "undefined") return [];
  try {
    const raw = localStorage.getItem(getStorageKey());
    return raw ? JSON.parse(raw) : [];
  } catch {
    return [];
  }
}

function markMedAsTaken(medId: string): void {
  if (typeof window === "undefined") return;
  const taken = getTakenMedIds();
  if (!taken.includes(medId)) {
    taken.push(medId);
    localStorage.setItem(getStorageKey(), JSON.stringify(taken));
  }
}

function playChime(): void {
  try {
    const AudioContext = window.AudioContext || (window as any).webkitAudioContext;
    if (!AudioContext) return;
    const ctx = new AudioContext();
    const now = ctx.currentTime;

    // First tone (higher)
    const osc1 = ctx.createOscillator();
    const gain1 = ctx.createGain();
    osc1.type = "sine";
    osc1.frequency.setValueAtTime(523.25, now); // C5
    gain1.gain.setValueAtTime(0.3, now);
    gain1.gain.exponentialRampToValueAtTime(0.01, now + 0.6);
    osc1.connect(gain1);
    gain1.connect(ctx.destination);
    osc1.start(now);
    osc1.stop(now + 0.6);

    // Second tone (lower, harmonious)
    const osc2 = ctx.createOscillator();
    const gain2 = ctx.createGain();
    osc2.type = "sine";
    osc2.frequency.setValueAtTime(659.25, now + 0.15); // E5
    gain2.gain.setValueAtTime(0.3, now + 0.15);
    gain2.gain.exponentialRampToValueAtTime(0.01, now + 0.9);
    osc2.connect(gain2);
    gain2.connect(ctx.destination);
    osc2.start(now + 0.15);
    osc2.stop(now + 0.9);

    // Third tone (resolution)
    const osc3 = ctx.createOscillator();
    const gain3 = ctx.createGain();
    osc3.type = "sine";
    osc3.frequency.setValueAtTime(783.99, now + 0.3); // G5
    gain3.gain.setValueAtTime(0.25, now + 0.3);
    gain3.gain.exponentialRampToValueAtTime(0.01, now + 1.2);
    osc3.connect(gain3);
    gain3.connect(ctx.destination);
    osc3.start(now + 0.3);
    osc3.stop(now + 1.2);
  } catch {
    // Silently fail if audio is not supported
  }
}

function speakMedication(drugName: string): void {
  if (typeof window === "undefined" || !window.speechSynthesis) return;

  const utterance = new SpeechSynthesisUtterance(
    `وقت تناول الدواء: ${drugName}`
  );
  utterance.lang = "ar-SA";
  utterance.rate = 0.9;
  utterance.pitch = 1.0;
  utterance.volume = 1.0;

  // Try to select an Arabic voice
  const voices = window.speechSynthesis.getVoices();
  const arVoice = voices.find(
    (v) => v.lang.startsWith("ar") || v.lang.startsWith("ar-SA")
  );
  if (arVoice) {
    utterance.voice = arVoice;
  }

  window.speechSynthesis.speak(utterance);
}

export function isMedTakenToday(medId: string): boolean {
  return getTakenMedIds().includes(medId);
}

export { markMedAsTaken };

export default function MedicationAlert({ patientId, medications }: MedicationAlertProps) {
  const [activeMed, setActiveMed] = useState<Medication | null>(null);
  const [queue, setQueue] = useState<Medication[]>([]);
  const [isVisible, setIsVisible] = useState(false);
  const hasSpokenRef = useRef<Set<string>>(new Set());
  const intervalRef = useRef<NodeJS.Timeout | null>(null);

  const checkMedications = useCallback(() => {
    const currentCategory = getCurrentTimeCategory();
    if (currentCategory === "other") {
      setIsVisible(false);
      setActiveMed(null);
      return;
    }

    const takenIds = getTakenMedIds();
    const dueMeds = medications.filter((med) => {
      const medCategory = getTimingCategory(med.timing);
      return medCategory === currentCategory && !takenIds.includes(med.id);
    });

    if (dueMeds.length === 0) {
      setIsVisible(false);
      setActiveMed(null);
      return;
    }

    // If not already showing an alert, show the first due med
    if (!isVisible && !activeMed) {
      const nextMed = dueMeds[0];
      setActiveMed(nextMed);
      setIsVisible(true);
      setQueue(dueMeds.slice(1));

      // Play chime
      playChime();

      // Speak only once per medication per session
      if (!hasSpokenRef.current.has(nextMed.id)) {
        speakMedication(nextMed.drugName);
        hasSpokenRef.current.add(nextMed.id);
      }
    }
  }, [medications, isVisible, activeMed]);

  useEffect(() => {
    // Initial check
    checkMedications();

    // Check every minute
    intervalRef.current = setInterval(checkMedications, 60_000);

    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, [checkMedications]);

  const handleTookIt = async () => {
    if (!activeMed) return;

    markMedAsTaken(activeMed.id);
    setIsVisible(false);
    setActiveMed(null);

    // Trigger server action for Telegram notification
    try {
      const { markMedicationAsTaken } = await import("@/app/actions/patient");
      await markMedicationAsTaken(activeMed.id, patientId);
    } catch (err) {
      console.error("[MedicationAlert] Failed to notify server:", err);
    }

    // Show next in queue after a short delay
    if (queue.length > 0) {
      setTimeout(() => {
        const nextMed = queue[0];
        setActiveMed(nextMed);
        setIsVisible(true);
        setQueue((prev) => prev.slice(1));

        playChime();
        if (!hasSpokenRef.current.has(nextMed.id)) {
          speakMedication(nextMed.drugName);
          hasSpokenRef.current.add(nextMed.id);
        }
      }, 500);
    }
  };

  const handleSpeakAgain = () => {
    if (activeMed) {
      speakMedication(activeMed.drugName);
    }
  };

  if (!isVisible || !activeMed) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm">
      <div className="mx-4 w-full max-w-lg rounded-3xl border-2 border-indigo-500/50 bg-zinc-900 p-8 text-center shadow-2xl shadow-indigo-500/20">
        {/* Icon */}
        <div className="mx-auto mb-6 flex h-24 w-24 items-center justify-center rounded-full bg-indigo-500/20">
          <Pill className="h-14 w-14 text-indigo-400" strokeWidth={2} />
        </div>

        {/* Arabic Title */}
        <h2 className="mb-2 text-5xl font-extrabold text-white">
          وقت الدواء!
        </h2>
        <p className="mb-8 text-2xl text-zinc-400">Time for Medicine!</p>

        {/* Drug Info */}
        <div className="mb-8 rounded-2xl border-2 border-zinc-700 bg-zinc-800/50 p-6">
          <p className="mb-2 text-4xl font-bold text-indigo-300">
            {activeMed.drugName}
          </p>
          <p className="text-2xl text-zinc-300">{activeMed.dosage}</p>
          {activeMed.timing && (
            <p className="mt-2 text-xl text-zinc-500">{activeMed.timing}</p>
          )}
        </div>

        {/* Speak Again Button */}
        <button
          onClick={handleSpeakAgain}
          className="mb-4 inline-flex items-center gap-2 rounded-xl bg-zinc-800 px-5 py-3 text-lg font-semibold text-zinc-300 transition-colors hover:bg-zinc-700"
        >
          <Volume2 className="h-5 w-5" />
          Listen Again
        </button>

        {/* Big Action Button */}
        <button
          onClick={handleTookIt}
          className="w-full rounded-2xl bg-emerald-500 py-6 text-3xl font-extrabold text-white shadow-lg shadow-emerald-500/30 transition-all hover:bg-emerald-400 hover:scale-[1.02] active:scale-[0.98]"
        >
          اخذته
          <span className="mt-1 block text-lg font-medium text-emerald-100">
            I took it
          </span>
        </button>
      </div>
    </div>
  );
}

