/*
 * File: patientCareSlice.ts
 * Description: Patient care state management slice
 * Design & Developed by Tech4Biz Solutions
 * Copyright (c) Spurrin Innovations. All rights reserved.
 */

import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import { patientAPI } from '../services/patientAPI';

// ============================================================================
// TYPES
// ============================================================================

/**
 * New API Response Types
 */
export interface SeriesSummary {
  series_num: string;
  series_description: string;
  total_images: number;
  png_preview: string;
  modality: string;
}

export interface PatientInfo {
  name: string;
  age: string;
  sex: string;
  date: string;
  institution: string;
  modality: string;
  status: string;
  report_status: string;
  file_name: string;
  file_type: string;
  frame_count: number;
}

export interface PatientData {
  patid: string;
  hospital_id: string;
  first_processed_at: string;
  last_processed_at: string;
  total_files_processed: number;
  patient_info: PatientInfo;
  series_summary: SeriesSummary[];
  processing_metadata: any;
}

export interface PatientCareState {
  // Patients data
  patients: PatientData[];
  currentPatient: PatientData | null;
  
  // Loading states
  isLoading: boolean;
  isRefreshing: boolean;
  isLoadingPatientDetails: boolean;
  
  // Error handling
  error: string | null;
  
  // Search and filtering
  searchQuery: string;
  selectedFilter: 'all' | 'processed' | 'pending' | 'error';
  sortBy: 'date' | 'name' | 'processed';
  sortOrder: 'asc' | 'desc';
  
  // Pagination
  currentPage: number;
  itemsPerPage: number;
  totalItems: number;
  
  // Cache
  lastUpdated: string | null;
  cacheExpiry: string | null;
}

// ============================================================================
// ASYNC THUNKS
// ============================================================================

/**
 * Fetch Patients Async Thunk
 * 
 * Purpose: Fetch patients list from API
 * 
 * @returns Promise with patients data or error
 */
export const fetchPatients = createAsyncThunk(
  'patientCare/fetchPatients',
  async (token: string, { rejectWithValue }) => {
    try {
      const response: any = await patientAPI.getPatients(token);
      
      if (response.ok && response.data&& response.data.data) {
        // Return the patients data directly from the new API structure
        return response.data.data as PatientData[];
      } else {
        // Fallback to mock data for development
        const mockPatients: PatientData[] = [
          {
            patid: "demo001",
            hospital_id: "demo-hospital-001",
            first_processed_at: "2025-01-15T10:30:00Z",
            last_processed_at: "2025-01-15T11:45:00Z",
            total_files_processed: 3,
            patient_info: {
              name: "John Doe",
              age: "38",
              sex: "M",
              date: "2025-01-15",
              institution: "City General Hospital",
              modality: "CT",
              status: "Processed",
              report_status: "Available",
              file_name: "chest_ct_001.dcm",
              file_type: "dcm",
              frame_count: 50
            },
            series_summary: [
              {
                series_num: "1",
                series_description: "Chest CT",
                total_images: 50,
                png_preview: "/images/ct_chest_1.png",
                modality: "CT"
              }
            ],
            processing_metadata: {}
          },
          {
            patid: "demo002",
            hospital_id: "demo-hospital-002",
            first_processed_at: "2025-01-15T09:15:00Z",
            last_processed_at: "2025-01-15T10:30:00Z",
            total_files_processed: 2,
            patient_info: {
              name: "Jane Smith",
              age: "33",
              sex: "F",
              date: "2025-01-15",
              institution: "Memorial Medical Center",
              modality: "MR",
              status: "Processed",
              report_status: "Available",
              file_name: "brain_mri_001.dcm",
              file_type: "dcm",
              frame_count: 120
            },
            series_summary: [
              {
                series_num: "1",
                series_description: "Brain MRI",
                total_images: 120,
                png_preview: "/images/mri_brain_1.png",
                modality: "MR"
              }
            ],
            processing_metadata: {}
          }
        ];
        
        return [];
      }
    } catch (error: any) {
      console.error('Fetch patients error:', error);
      return rejectWithValue(error.message || 'Failed to fetch patients.');
    }
  }
);

/**
 * Fetch Patient Details Async Thunk
 * 
 * Purpose: Fetch detailed patient information
 * 
 * @param patientId - ID of the patient to fetch
 * @returns Promise with patient details or error
 */
export const fetchPatientDetails = createAsyncThunk(
  'patientCare/fetchPatientDetails',
  async (patientId: string, { rejectWithValue }) => {
    try {
      // TODO: Replace with actual API call
      await new Promise((resolve) => setTimeout(resolve as any, 1000));
      
      // Mock patient details for specific patient
      const mockPatient: PatientData = {
        patid: patientId,
        hospital_id: `demo-hospital-${patientId}`,
        first_processed_at: "2025-01-15T10:30:00Z",
        last_processed_at: "2025-01-15T11:45:00Z",
        total_files_processed: 3,
        patient_info: {
          name: `Patient ${patientId}`,
          age: "38",
          sex: "M",
          date: "2025-01-15",
          institution: "City General Hospital",
          modality: "CT",
          status: "Processed",
          report_status: "Available",
          file_name: `patient_${patientId}.dcm`,
          file_type: "dcm",
          frame_count: 50
        },
        series_summary: [
          {
            series_num: "1",
            series_description: "Chest CT",
            total_images: 50,
            png_preview: `/images/ct_chest_${patientId}.png`,
            modality: "CT"
          }
        ],
        processing_metadata: {}
      };
      
      return mockPatient;
    } catch (error) {
      return rejectWithValue('Failed to fetch patient details.');
    }
  }
);

/**
 * Update Patient Async Thunk
 * 
 * Purpose: Update patient information
 * 
 * @param patientData - Updated patient data
 * @returns Promise with updated patient or error
 */
export const updatePatient = createAsyncThunk(
  'patientCare/updatePatient',
  async (patientData: Partial<PatientData> & { patid: string }, { rejectWithValue }) => {
    try {
      // TODO: Replace with actual API call
      await new Promise((resolve) => setTimeout(resolve as any, 800));
      return patientData;
    } catch (error) {
      return rejectWithValue('Failed to update patient.');
    }
  }
);

// ============================================================================
// INITIAL STATE
// ============================================================================

/**
 * Initial Patient Care State
 * 
 * Purpose: Define the initial state for patient care
 * 
 * Features:
 * - Patients list and management
 * - Current patient details
 * - Loading states for async operations
 * - Error handling and messages
 * - Search and filtering
 * - Pagination and caching
 */
const initialState: PatientCareState = {
  // Patients data
  patients: [],
  currentPatient: null,
  
  // Loading states
  isLoading: false,
  isRefreshing: false,
  isLoadingPatientDetails: false,
  
  // Error handling
  error: null,
  
  // Search and filtering
  searchQuery: '',
  selectedFilter: 'all',
  sortBy: 'date',
  sortOrder: 'desc',
  
  // Pagination
  currentPage: 1,
  itemsPerPage: 20,
  totalItems: 0,
  
  // Cache
  lastUpdated: null,
  cacheExpiry: null,
};

// ============================================================================
// PATIENT CARE SLICE
// ============================================================================

/**
 * Patient Care Slice
 * 
 * Purpose: Redux slice for patient care state management
 * 
 * Features:
 * - Patient data management
 * - Search and filtering
 * - Pagination
 * - Caching
 * - Error handling
 * - Loading states
 */
const patientCareSlice = createSlice({
  name: 'patientCare',
  initialState,
  reducers: {
    /**
     * Clear Error Action
     * 
     * Purpose: Clear patient care errors
     */
    clearError: (state) => {
      state.error = null;
    },
    
    /**
     * Set Search Query Action
     * 
     * Purpose: Set search query for patients
     */
    setSearchQuery: (state, action: PayloadAction<string>) => {
      state.searchQuery = action.payload;
      state.currentPage = 1; // Reset to first page when searching
    },
    
    /**
     * Set Filter Action
     * 
     * Purpose: Set patient filter
     */
    setFilter: (state, action: PayloadAction<'all' | 'processed' | 'pending' | 'error'>) => {
      state.selectedFilter = action.payload;
      state.currentPage = 1; // Reset to first page when filtering
    },
    
    /**
     * Set Sort Action
     * 
     * Purpose: Set patient sort options
     */
    setSort: (state, action: PayloadAction<{ by: 'date' | 'name' | 'processed'; order: 'asc' | 'desc' }>) => {
      state.sortBy = action.payload.by;
      state.sortOrder = action.payload.order;
    },
    
    /**
     * Set Current Page Action
     * 
     * Purpose: Set current page for pagination
     */
    setCurrentPage: (state, action: PayloadAction<number>) => {
      state.currentPage = action.payload;
    },
    
    /**
     * Set Items Per Page Action
     * 
     * Purpose: Set items per page for pagination
     */
    setItemsPerPage: (state, action: PayloadAction<number>) => {
      state.itemsPerPage = action.payload;
      state.currentPage = 1; // Reset to first page when changing items per page
    },
    
    /**
     * Set Current Patient Action
     * 
     * Purpose: Set the currently selected patient
     */
    setCurrentPatient: (state, action: PayloadAction<PatientData | null>) => {
      state.currentPatient = action.payload;
    },
    
    /**
     * Update Patient in List Action
     * 
     * Purpose: Update a patient in the patients list
     */
    updatePatientInList: (state, action: PayloadAction<PatientData>) => {
      const index = state.patients.findIndex(patient => patient.patid === action.payload.patid);
      if (index !== -1) {
        state.patients[index] = action.payload;
      }
      
      // Update current patient if it's the same patient
      if (state.currentPatient && state.currentPatient.patid === action.payload.patid) {
        state.currentPatient = action.payload;
      }
    },
    
    /**
     * Add Patient Action
     * 
     * Purpose: Add a new patient to the list
     */
    addPatient: (state, action: PayloadAction<PatientData>) => {
      state.patients.unshift(action.payload);
      state.totalItems += 1;
    },
    
    /**
     * Remove Patient Action
     * 
     * Purpose: Remove a patient from the list
     */
    removePatient: (state, action: PayloadAction<string>) => {
      const index = state.patients.findIndex(patient => patient.patid === action.payload);
      if (index !== -1) {
        state.patients.splice(index, 1);
        state.totalItems -= 1;
      }
      
      // Clear current patient if it's the same patient
      if (state.currentPatient && state.currentPatient.patid === action.payload) {
        state.currentPatient = null;
      }
    },
    
    /**
     * Clear Cache Action
     * 
     * Purpose: Clear patient data cache
     */
    clearCache: (state) => {
      state.patients = [];
      state.currentPatient = null;
      state.lastUpdated = null;
      state.cacheExpiry = null;
    },
  },
  extraReducers: (builder) => {
    // Fetch Patients
    builder
      .addCase(fetchPatients.pending, (state) => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(fetchPatients.fulfilled, (state, action) => {
        state.isLoading = false;
        state.patients = action.payload;
        state.totalItems = action.payload.length;
        state.lastUpdated = new Date().toLocaleDateString();
        state.cacheExpiry = new Date(Date.now() + 5 * 60 * 1000).toLocaleDateString(); // 5 minutes
        state.error = null;
      })
      .addCase(fetchPatients.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload as string;
      });
    
    // Fetch Patient Details
    builder
      .addCase(fetchPatientDetails.pending, (state) => {
        state.isLoadingPatientDetails = true;
        state.error = null;
      })
      .addCase(fetchPatientDetails.fulfilled, (state, action) => {
        state.isLoadingPatientDetails = false;
        state.currentPatient = action.payload;
        state.error = null;
      })
      .addCase(fetchPatientDetails.rejected, (state, action) => {
        state.isLoadingPatientDetails = false;
        state.error = action.payload as string;
      });
    
    // Update Patient
    builder
      .addCase(updatePatient.fulfilled, (state, action) => {
        // Update patient in list
        const index = state.patients.findIndex(patient => patient.patid === action.payload.patid);
        if (index !== -1) {
          state.patients[index] = { ...state.patients[index], ...action.payload };
        }
        
        // Update current patient if it's the same patient
        if (state.currentPatient && state.currentPatient.patid === action.payload.patid) {
          state.currentPatient = { ...state.currentPatient, ...action.payload };
        }
      })
      .addCase(updatePatient.rejected, (state, action) => {
        state.error = action.payload as string;
      });
  },
});

// ============================================================================
// EXPORTS
// ============================================================================

export const {
  clearError,
  setSearchQuery,
  setFilter,
  setSort,
  setCurrentPage,
  setItemsPerPage,
  setCurrentPatient,
  updatePatientInList,
  addPatient,
  removePatient,
  clearCache,
} = patientCareSlice.actions;

export default patientCareSlice.reducer;

/*
 * End of File: patientCareSlice.ts
 * Design & Developed by Tech4Biz Solutions
 * Copyright (c) Spurrin Innovations. All rights reserved.
 */ 