/*
 * File: patientCareSelectors.ts
 * Description: Redux selectors for patient care state
 * Design & Developed by Tech4Biz Solutions
 * Copyright (c) Spurrin Innovations. All rights reserved.
 */

import { createSelector } from '@reduxjs/toolkit';
import { RootState } from '../../../store';
import { PatientData } from './patientCareSlice';

// ============================================================================
// BASE SELECTORS
// ============================================================================

/**
 * Select Patient Care State
 * 
 * Purpose: Get the entire patient care state
 */
export const selectPatientCareState = (state: RootState) => state.patientCare;

/**
 * Select Patients
 * 
 * Purpose: Get the patients array
 */
export const selectPatients = (state: RootState) => state.patientCare.patients;

/**
 * Select Current Patient
 * 
 * Purpose: Get the currently selected patient
 */
export const selectCurrentPatient = (state: RootState) => state.patientCare.currentPatient;

/**
 * Select Patients Loading State
 * 
 * Purpose: Get the loading state for patients
 */
export const selectPatientsLoading = (state: RootState) => state.patientCare.isLoading;

/**
 * Select Is Refreshing State
 * 
 * Purpose: Get the refreshing state for pull-to-refresh
 */
export const selectIsRefreshing = (state: RootState) => state.patientCare.isRefreshing;

/**
 * Select Patient Details Loading State
 * 
 * Purpose: Get the loading state for patient details
 */
export const selectPatientDetailsLoading = (state: RootState) => state.patientCare.isLoadingPatientDetails;

/**
 * Select Patients Error
 * 
 * Purpose: Get the error state for patients
 */
export const selectPatientsError = (state: RootState) => state.patientCare.error;

/**
 * Select Search Query
 * 
 * Purpose: Get the current search query
 */
export const selectSearchQuery = (state: RootState) => state.patientCare.searchQuery;

/**
 * Select Selected Filter
 * 
 * Purpose: Get the currently selected filter
 */
export const selectSelectedFilter = (state: RootState) => state.patientCare.selectedFilter;

/**
 * Select Sort By
 * 
 * Purpose: Get the current sort option
 */
export const selectSortBy = (state: RootState) => state.patientCare.sortBy;

/**
 * Select Sort Order
 * 
 * Purpose: Get the current sort order
 */
export const selectSortOrder = (state: RootState) => state.patientCare.sortOrder;

/**
 * Select Pagination Info
 * 
 * Purpose: Get pagination-related state
 */
export const selectPaginationInfo = (state: RootState) => ({
  currentPage: state.patientCare.currentPage,
  itemsPerPage: state.patientCare.itemsPerPage,
  totalItems: state.patientCare.totalItems,
});

/**
 * Select Last Updated
 * 
 * Purpose: Get the last updated timestamp
 */
export const selectLastUpdated = (state: RootState) => state.patientCare.lastUpdated;

// ============================================================================
// COMPUTED SELECTORS
// ============================================================================

/**
 * Select Filtered Patients
 * 
 * Purpose: Get patients filtered by search query and selected filter
 */
export const selectFilteredPatients = createSelector(
  [selectPatients, selectSearchQuery, selectSelectedFilter, selectSortBy, selectSortOrder],
  (patients, searchQuery, selectedFilter, sortBy, sortOrder) => {
    // Ensure patients is always an array
    if (!patients || !Array.isArray(patients)) {
      return [];
    }
    
    let filteredPatients = [...patients];

    // Apply filter based on processing status
    if (selectedFilter !== 'all') {
      filteredPatients = filteredPatients.filter((patient: PatientData) => {
        const status = patient.patient_info.status.toLowerCase();
        return status === selectedFilter;
      });
    }

    // Apply search
    if (searchQuery.trim()) {
      const query = searchQuery.toLowerCase().trim();
      filteredPatients = filteredPatients.filter((patient: PatientData) => {
        const patientInfo = patient.patient_info;
        
        const name = (patientInfo.name || '').toLowerCase();
        const patId = (patient.patid || '').toLowerCase();
        const institution = (patientInfo.institution || '').toLowerCase();
        const modality = (patientInfo.modality || '').toLowerCase();
        
        return (
          name.includes(query) ||
          patId.includes(query) ||
          institution.includes(query) ||
          modality.includes(query)
        );
      });
    }

    // Apply sorting
    filteredPatients.sort((a: PatientData, b: PatientData) => {
      let aValue: any;
      let bValue: any;

      switch (sortBy) {
        case 'name':
          aValue = (a.patient_info.name || '').toLowerCase();
          bValue = (b.patient_info.name || '').toLowerCase();
          break;
        case 'processed':
          aValue = new Date(a.last_processed_at).getTime();
          bValue = new Date(b.last_processed_at).getTime();
          break;
        case 'date':
        default:
          aValue = new Date(a.patient_info.date).getTime();
          bValue = new Date(b.patient_info.date).getTime();
          break;
      }

      if (aValue < bValue) {
        return sortOrder === 'asc' ? -1 : 1;
      }
      if (aValue > bValue) {
        return sortOrder === 'asc' ? 1 : -1;
      }
      return 0;
    });

    return filteredPatients;
  }
);

/**
 * Select Processed Patients
 * 
 * Purpose: Get patients with processed status
 */
export const selectProcessedPatients = createSelector(
  [selectPatients],
  (patients) => {
    if (!patients || !Array.isArray(patients)) return [];
    return patients.filter((patient: PatientData) => 
      patient.patient_info.status.toLowerCase() === 'processed'
    );
  }
);

/**
 * Select Pending Patients
 * 
 * Purpose: Get patients with pending status
 */
export const selectPendingPatients = createSelector(
  [selectPatients],
  (patients) => {
    if (!patients || !Array.isArray(patients)) return [];
    return patients.filter((patient: PatientData) => 
      patient.patient_info.status.toLowerCase() === 'pending'
    );
  }
);

/**
 * Select Error Patients
 * 
 * Purpose: Get patients with error status
 */
export const selectErrorPatients = createSelector(
  [selectPatients],
  (patients) => {
    if (!patients || !Array.isArray(patients)) return [];
    return patients.filter((patient: PatientData) => 
      patient.patient_info.status.toLowerCase() === 'error'
    );
  }
);

/**
 * Select Patients by Modality
 * 
 * Purpose: Get patients grouped by imaging modality
 */
export const selectPatientsByModality = createSelector(
  [selectPatients],
  (patients) => {
    if (!patients || !Array.isArray(patients)) return {};
    
    const grouped: { [key: string]: PatientData[] } = {};
    
    patients.forEach((patient: PatientData) => {
      const modality = patient.patient_info.modality || 'Unknown';
      if (!grouped[modality]) {
        grouped[modality] = [];
      }
      grouped[modality].push(patient);
    });
    
    return grouped;
  }
);

/**
 * Select Patient Statistics
 * 
 * Purpose: Get statistics about patients
 */
export const selectPatientStats = createSelector(
  [selectPatients],
  (patients) => {
    if (!patients || !Array.isArray(patients)) {
      return {
        total: 0,
        processed: 0,
        pending: 0,
        error: 0,
        averageAge: 0,
        modalities: {},
        totalFiles: 0,
        processedPercentage: 0,
        pendingPercentage: 0,
        errorPercentage: 0,
      };
    }
    
    const total = patients.length;
    const processed = patients.filter((p: PatientData) => p.patient_info.status.toLowerCase() === 'processed').length;
    const pending = patients.filter((p: PatientData) => p.patient_info.status.toLowerCase() === 'pending').length;
    const error = patients.filter((p: PatientData) => p.patient_info.status.toLowerCase() === 'error').length;
    
    // Calculate average age
    const totalAge = patients.reduce((sum: number, patient: PatientData) => {
      const age = parseInt(patient.patient_info.age) || 0;
      return sum + age;
    }, 0);
    const averageAge = total > 0 ? Math.round(totalAge / total) : 0;
    
    // Modality distribution
    const modalities: { [key: string]: number } = {};
    patients.forEach((patient: PatientData) => {
      const modality = patient.patient_info.modality || 'Unknown';
      modalities[modality] = (modalities[modality] || 0) + 1;
    });
    
    // Total files processed
    const totalFiles = patients.reduce((sum: number, patient: PatientData) => sum + (patient.total_files_processed || 0), 0);
    
    return {
      total,
      processed,
      pending,
      error,
      averageAge,
      modalities,
      totalFiles,
      processedPercentage: total > 0 ? Math.round((processed / total) * 100) : 0,
      pendingPercentage: total > 0 ? Math.round((pending / total) * 100) : 0,
      errorPercentage: total > 0 ? Math.round((error / total) * 100) : 0,
    };
  }
);

/**
 * Select Patient by ID
 * 
 * Purpose: Get a specific patient by ID
 * 
 * @param patientId - The ID of the patient to find
 */
export const selectPatientById = (patientId: string) =>
  createSelector(
    [selectPatients],
    (patients) => {
      if (!patients || !Array.isArray(patients)) return undefined;
      return patients.find((patient: PatientData) => patient.patid === patientId);
    }
  );

/**
 * Select Patients Need Attention
 * 
 * Purpose: Get patients that need immediate attention
 */
export const selectPatientsNeedAttention = createSelector(
  [selectPatients],
  (patients) => {
    if (!patients || !Array.isArray(patients)) return [];
    
    return patients.filter((patient: PatientData) => {
      // Error patients always need attention
      if (patient.patient_info.status.toLowerCase() === 'error') return true;
      
      // Patients with critical report status
      if (patient.patient_info.report_status.toLowerCase() === 'critical') return true;
      
      // Patients with high frame count (complex cases)
      if (patient.patient_info.frame_count > 100) return true;
      
      // Patients with multiple series (complex cases)
      if (patient.series_summary.length > 5) return true;
      
      return false;
    });
  }
);

/**
 * Select Has Data
 * 
 * Purpose: Check if we have patient data
 */
export const selectHasPatientData = createSelector(
  [selectPatients],
  (patients) => patients && Array.isArray(patients) && patients.length > 0
);

/**
 * Select Is Empty State
 * 
 * Purpose: Check if we should show empty state
 */
export const selectIsEmptyState = createSelector(
  [selectPatients, selectPatientsLoading, selectFilteredPatients],
  (patients, isLoading, filteredPatients) => 
    !isLoading && patients && Array.isArray(patients) && patients.length > 0 && filteredPatients.length === 0
);

/**
 * Select Patient Counts for Filters
 * 
 * Purpose: Get patient counts for each filter category
 */
export const selectPatientCounts = createSelector(
  [selectPatients],
  (patients) => {
    if (!patients || !Array.isArray(patients)) {
      return { all: 0, processed: 0, pending: 0, error: 0 };
    }
    
    return {
      all: patients.length,
      processed: patients.filter((p: PatientData) => p.patient_info.status.toLowerCase() === 'processed').length,
      pending: patients.filter((p: PatientData) => p.patient_info.status.toLowerCase() === 'pending').length,
      error: patients.filter((p: PatientData) => p.patient_info.status.toLowerCase() === 'error').length,
    };
  }
);

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