import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import type { Beneficiary, BeneficiarySubscription } from '@/types';

const LOCAL_BENEFICIARIES_KEY = 'wellnuo_local_beneficiaries';

interface AddBeneficiaryData {
  name: string;
  address?: string;
  avatar?: string;
  subscription?: BeneficiarySubscription;
}

interface BeneficiaryContextType {
  currentBeneficiary: Beneficiary | null;
  setCurrentBeneficiary: (beneficiary: Beneficiary | null) => void;
  clearCurrentBeneficiary: () => void;
  // Local beneficiaries management (for users without API deployments)
  localBeneficiaries: Beneficiary[];
  addLocalBeneficiary: (data: string | AddBeneficiaryData) => Promise<Beneficiary>;
  updateLocalBeneficiary: (id: number, data: Partial<Beneficiary>) => Promise<Beneficiary | null>;
  removeLocalBeneficiary: (id: number) => Promise<void>;
  // Clear all data (used on logout)
  clearAllBeneficiaryData: () => Promise<void>;
  // Helper to format beneficiary context for AI
  getBeneficiaryContext: () => string;
}

const BeneficiaryContext = createContext<BeneficiaryContextType | undefined>(undefined);

export function BeneficiaryProvider({ children }: { children: React.ReactNode }) {
  const [currentBeneficiary, setCurrentBeneficiary] = useState<Beneficiary | null>(null);
  const [localBeneficiaries, setLocalBeneficiaries] = useState<Beneficiary[]>([]);

  // Load local beneficiaries on mount
  useEffect(() => {
    loadLocalBeneficiaries();
  }, []);

  const loadLocalBeneficiaries = async () => {
    try {
      const stored = await AsyncStorage.getItem(LOCAL_BENEFICIARIES_KEY);
      if (stored) {
        setLocalBeneficiaries(JSON.parse(stored));
      }
    } catch (error) {
      console.error('Failed to load local beneficiaries:', error);
    }
  };

  const saveLocalBeneficiaries = async (beneficiaries: Beneficiary[]) => {
    try {
      await AsyncStorage.setItem(LOCAL_BENEFICIARIES_KEY, JSON.stringify(beneficiaries));
    } catch (error) {
      console.error('Failed to save local beneficiaries:', error);
    }
  };

  const addLocalBeneficiary = useCallback(async (data: string | AddBeneficiaryData): Promise<Beneficiary> => {
    // Support both string (legacy) and object format
    const beneficiaryData: AddBeneficiaryData = typeof data === 'string'
      ? { name: data }
      : data;

    const newBeneficiary: Beneficiary = {
      id: Date.now(), // Use timestamp as unique ID
      name: beneficiaryData.name.trim(),
      address: beneficiaryData.address?.trim(),
      avatar: beneficiaryData.avatar,
      status: 'offline',
      last_activity: 'Just added',
      subscription: beneficiaryData.subscription,
    };

    const updated = [...localBeneficiaries, newBeneficiary];
    setLocalBeneficiaries(updated);
    await saveLocalBeneficiaries(updated);

    // Auto-select if first beneficiary
    if (localBeneficiaries.length === 0) {
      setCurrentBeneficiary(newBeneficiary);
    }

    return newBeneficiary;
  }, [localBeneficiaries]);

  const updateLocalBeneficiary = useCallback(async (id: number, data: Partial<Beneficiary>): Promise<Beneficiary | null> => {
    const index = localBeneficiaries.findIndex(b => b.id === id);
    if (index === -1) return null;

    const updatedBeneficiary = { ...localBeneficiaries[index], ...data };
    const updated = [...localBeneficiaries];
    updated[index] = updatedBeneficiary;

    setLocalBeneficiaries(updated);
    await saveLocalBeneficiaries(updated);

    // Update current if it's the same beneficiary
    if (currentBeneficiary?.id === id) {
      setCurrentBeneficiary(updatedBeneficiary);
    }

    return updatedBeneficiary;
  }, [localBeneficiaries, currentBeneficiary]);

  const removeLocalBeneficiary = useCallback(async (id: number) => {
    const updated = localBeneficiaries.filter(b => b.id !== id);
    setLocalBeneficiaries(updated);
    await saveLocalBeneficiaries(updated);

    // Clear current if removed
    if (currentBeneficiary?.id === id) {
      setCurrentBeneficiary(updated[0] || null);
    }
  }, [localBeneficiaries, currentBeneficiary]);

  const clearCurrentBeneficiary = useCallback(() => {
    setCurrentBeneficiary(null);
  }, []);

  // Clear all beneficiary data (called on logout)
  const clearAllBeneficiaryData = useCallback(async () => {
    setCurrentBeneficiary(null);
    setLocalBeneficiaries([]);
    await AsyncStorage.removeItem(LOCAL_BENEFICIARIES_KEY);
  }, []);

  const getBeneficiaryContext = useCallback(() => {
    if (!currentBeneficiary) {
      return '';
    }

    const b = currentBeneficiary;
    const contextParts: string[] = [];

    // Basic info
    contextParts.push(`Person: ${b.name}`);

    if (b.address) {
      contextParts.push(`Address: ${b.address}`);
    }

    // Current status
    if (b.last_location) {
      contextParts.push(`Current location: ${b.last_location}`);
    }

    if (b.before_last_location) {
      contextParts.push(`Previous location: ${b.before_last_location}`);
    }

    // Health metrics
    if (b.wellness_score !== undefined) {
      contextParts.push(`Wellness score: ${b.wellness_score}% (${b.wellness_descriptor || 'N/A'})`);
    }

    // Temperature
    if (b.temperature !== undefined) {
      const unit = b.units || '°F';
      contextParts.push(`Room temperature: ${b.temperature.toFixed(1)}${unit}`);
    }

    if (b.bedroom_temperature !== undefined) {
      const unit = b.units || '°F';
      contextParts.push(`Bedroom temperature: ${b.bedroom_temperature.toFixed(1)}${unit}`);
    }

    // Sleep data
    if (b.sleep_hours !== undefined) {
      contextParts.push(`Sleep hours: ${b.sleep_hours.toFixed(1)} hours`);
    }

    // Activity time
    if (b.last_detected_time) {
      contextParts.push(`Last detected: ${b.last_detected_time}`);
    }

    // Status
    contextParts.push(`Status: ${b.status === 'online' ? 'Active' : 'Inactive'}`);

    return `[SENSOR DATA FOR ${b.name.toUpperCase()}: ${contextParts.join('. ')}]`;
  }, [currentBeneficiary]);

  return (
    <BeneficiaryContext.Provider
      value={{
        currentBeneficiary,
        setCurrentBeneficiary,
        clearCurrentBeneficiary,
        localBeneficiaries,
        addLocalBeneficiary,
        updateLocalBeneficiary,
        removeLocalBeneficiary,
        clearAllBeneficiaryData,
        getBeneficiaryContext,
      }}
    >
      {children}
    </BeneficiaryContext.Provider>
  );
}

export function useBeneficiary() {
  const context = useContext(BeneficiaryContext);
  if (context === undefined) {
    throw new Error('useBeneficiary must be used within a BeneficiaryProvider');
  }
  return context;
}
