import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware';
import { User, Medication, HealthStat, DrugInteraction } from '../types/api';
import apiService from '../services/api';

interface AuthState {
  user: User | null;
  token: string | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
  
  // Actions
  login: (email: string, password: string) => Promise<void>;
  register: (username: string, email: string, password: string) => Promise<void>;
  logout: () => void;
  clearError: () => void;
  loadUser: () => Promise<void>;
}

interface MedicationState {
  medications: Medication[];
  selectedMedication: Medication | null;
  isLoading: boolean;
  error: string | null;
  
  // Actions
  loadMedications: () => Promise<void>;
  createMedication: (data: any) => Promise<void>;
  updateMedication: (id: string, data: any) => Promise<void>;
  deleteMedication: (id: string) => Promise<void>;
  selectMedication: (medication: Medication | null) => void;
  clearError: () => void;
}

interface HealthState {
  stats: HealthStat[];
  trends: any[];
  isLoading: boolean;
  error: string | null;
  
  // Actions
  loadStats: () => Promise<void>;
  createStat: (data: any) => Promise<void>;
  updateStat: (id: string, data: any) => Promise<void>;
  deleteStat: (id: string) => Promise<void>;
  loadTrends: () => Promise<void>;
  clearError: () => void;
}

interface InteractionState {
  interactions: DrugInteraction[];
  isChecking: boolean;
  error: string | null;
  
  // Actions
  checkInteractions: (medications: string[]) => Promise<void>;
  checkNewMedication: (name: string, dosage: string) => Promise<void>;
  clearInteractions: () => void;
  clearError: () => void;
}

// Auth Store
export const useAuthStore = create<AuthState>()(
  devtools(
    persist(
      (set, get) => ({
        user: null,
        token: null,
        isAuthenticated: false,
        isLoading: false,
        error: null,

        login: async (email: string, password: string) => {
          set({ isLoading: true, error: null });
          try {
            const response = await apiService.login(email, password);
            set({
              user: {
                user_id: response.user_id,
                username: response.username,
                email: email,
                role: 'patient',
              },
              token: response.token,
              isAuthenticated: true,
              isLoading: false,
            });
          } catch (error: any) {
            set({
              error: error.message || 'Login failed',
              isLoading: false,
              isAuthenticated: false,
            });
            throw error;
          }
        },

        register: async (username: string, email: string, password: string) => {
          set({ isLoading: true, error: null });
          try {
            const response = await apiService.register({
              username,
              email,
              password,
              role: 'patient',
            });
            set({
              user: {
                user_id: response.user_id,
                username: response.username,
                email: email,
                role: 'patient',
              },
              token: response.token,
              isAuthenticated: true,
              isLoading: false,
            });
          } catch (error: any) {
            set({
              error: error.message || 'Registration failed',
              isLoading: false,
              isAuthenticated: false,
            });
            throw error;
          }
        },

        logout: () => {
          apiService.logout();
          set({
            user: null,
            token: null,
            isAuthenticated: false,
            error: null,
          });
        },

        clearError: () => set({ error: null }),

        loadUser: async () => {
          const token = get().token;
          if (!token) return;
          
          set({ isLoading: true });
          try {
            const user = await apiService.getCurrentUser();
            set({
              user,
              isAuthenticated: true,
              isLoading: false,
            });
          } catch (error: any) {
            set({
              error: error.message,
              isLoading: false,
              isAuthenticated: false,
            });
          }
        },
      }),
      {
        name: 'normogen-auth',
        partialize: (state) => ({
          token: state.token,
          user: state.user,
          isAuthenticated: state.isAuthenticated,
        }),
      }
    )
  )
);

// Medication Store
export const useMedicationStore = create<MedicationState>()(
  devtools((set, get) => ({
    medications: [],
    selectedMedication: null,
    isLoading: false,
    error: null,

    loadMedications: async () => {
      set({ isLoading: true, error: null });
      try {
        const medications = await apiService.getMedications();
        set({ medications, isLoading: false });
      } catch (error: any) {
        set({
          error: error.message || 'Failed to load medications',
          isLoading: false,
        });
      }
    },

    createMedication: async (data: any) => {
      set({ isLoading: true, error: null });
      try {
        const medication = await apiService.createMedication(data);
        set((state) => ({
          medications: [...state.medications, medication],
          isLoading: false,
        }));
      } catch (error: any) {
        set({
          error: error.message || 'Failed to create medication',
          isLoading: false,
        });
        throw error;
      }
    },

    updateMedication: async (id: string, data: any) => {
      set({ isLoading: true, error: null });
      try {
        const updated = await apiService.updateMedication(id, data);
        set((state) => ({
          medications: state.medications.map((med) =>
            med.medication_id === id ? updated : med
          ),
          isLoading: false,
        }));
      } catch (error: any) {
        set({
          error: error.message || 'Failed to update medication',
          isLoading: false,
        });
        throw error;
      }
    },

    deleteMedication: async (id: string) => {
      set({ isLoading: true, error: null });
      try {
        await apiService.deleteMedication(id);
        set((state) => ({
          medications: state.medications.filter(
            (med) => med.medication_id !== id
          ),
          isLoading: false,
        }));
      } catch (error: any) {
        set({
          error: error.message || 'Failed to delete medication',
          isLoading: false,
        });
        throw error;
      }
    },

    selectMedication: (medication) => {
      set({ selectedMedication: medication });
    },

    clearError: () => set({ error: null }),
  }))
);

// Health Store
export const useHealthStore = create<HealthState>()(
  devtools((set, get) => ({
    stats: [],
    trends: [],
    isLoading: false,
    error: null,

    loadStats: async () => {
      set({ isLoading: true, error: null });
      try {
        const stats = await apiService.getHealthStats();
        set({ stats, isLoading: false });
      } catch (error: any) {
        set({
          error: error.message || 'Failed to load health stats',
          isLoading: false,
        });
      }
    },

    createStat: async (data: any) => {
      set({ isLoading: true, error: null });
      try {
        const stat = await apiService.createHealthStat(data);
        set((state) => ({
          stats: [...state.stats, stat],
          isLoading: false,
        }));
      } catch (error: any) {
        set({
          error: error.message || 'Failed to create stat',
          isLoading: false,
        });
        throw error;
      }
    },

    updateStat: async (id: string, data: any) => {
      set({ isLoading: true, error: null });
      try {
        const updated = await apiService.updateHealthStat(id, data);
        set((state) => ({
          stats: state.stats.map((stat) =>
            stat.stat_id === id ? updated : stat
          ),
          isLoading: false,
        }));
      } catch (error: any) {
        set({
          error: error.message || 'Failed to update stat',
          isLoading: false,
        });
        throw error;
      }
    },

    deleteStat: async (id: string) => {
      set({ isLoading: true, error: null });
      try {
        await apiService.deleteHealthStat(id);
        set((state) => ({
          stats: state.stats.filter((stat) => stat.stat_id !== id),
          isLoading: false,
        }));
      } catch (error: any) {
        set({
          error: error.message || 'Failed to delete stat',
          isLoading: false,
        });
        throw error;
      }
    },

    loadTrends: async () => {
      set({ isLoading: true, error: null });
      try {
        const trends = await apiService.getHealthTrends();
        set({ trends, isLoading: false });
      } catch (error: any) {
        set({
          error: error.message || 'Failed to load trends',
          isLoading: false,
        });
      }
    },

    clearError: () => set({ error: null }),
  }))
);

// Interaction Store (Phase 2.8)
export const useInteractionStore = create<InteractionState>()(
  devtools((set, get) => ({
    interactions: [],
    isChecking: false,
    error: null,

    checkInteractions: async (medications: string[]) => {
      set({ isChecking: true, error: null });
      try {
        const interactions = await apiService.checkInteractions(medications);
        set({ interactions, isChecking: false });
      } catch (error: any) {
        set({
          error: error.message || 'Failed to check interactions',
          isChecking: false,
        });
      }
    },

    checkNewMedication: async (name: string, dosage: string) => {
      set({ isChecking: true, error: null });
      try {
        const interactions = await apiService.checkNewMedication(name, dosage);
        set({ interactions, isChecking: false });
      } catch (error: any) {
        set({
          error: error.message || 'Failed to check medication',
          isChecking: false,
        });
      }
    },

    clearInteractions: () => set({ interactions: [] }),
    clearError: () => set({ error: null }),
  }))
);
