import apiService from '../services/apiService';
import { fetchCurrentUserProfile } from '../services/userProfileService';

let cachedHospitalName: string | null = null;
let cachedPhccSiteName: string | null = null;
let fetchPromise: Promise<UserLocationFilters> | null = null;

export interface UserLocationFilters {
  hospital: string;
  siteName: string;
  isLocked: boolean;
  allowedHospitals: string[];
}

async function fetchAllowedHospitals(): Promise<string[]> {
  try {
    const [companyRes, hospitalRes] = await Promise.all([
      apiService.getAllowedValues('Company'),
      apiService.getAllowedValues('Hospital'),
    ]);

    if (companyRes.is_admin || hospitalRes.is_admin) {
      return [];
    }

    const values = new Set<string>();
    if (companyRes.has_restriction) {
      companyRes.allowed_values.forEach((value) => values.add(value));
    }
    if (hospitalRes.has_restriction) {
      hospitalRes.allowed_values.forEach((value) => values.add(value));
    }

    return Array.from(values).sort();
  } catch (error) {
    console.error('[userHospital] Failed to load allowed hospitals:', error);
    return [];
  }
}

function resolveDefaultHospital(
  profileHospital: string,
  allowedHospitals: string[],
  permissionDefault?: string | null
): string {
  if (allowedHospitals.length === 1) {
    return allowedHospitals[0];
  }

  if (profileHospital && (!allowedHospitals.length || allowedHospitals.includes(profileHospital))) {
    return profileHospital;
  }

  if (permissionDefault && allowedHospitals.includes(permissionDefault)) {
    return permissionDefault;
  }

  return '';
}

function resolveHospitalLock(allowedHospitals: string[], profileHospital: string): boolean {
  if (allowedHospitals.length === 1) {
    return true;
  }

  if (allowedHospitals.length > 1) {
    return false;
  }

  return !!profileHospital;
}

export function getStoredHospitalName(): string {
  try {
    const user = localStorage.getItem('user');
    if (!user) {
      return '';
    }
    const parsed = JSON.parse(user);
    return parsed.custom_site_name || '';
  } catch {
    return '';
  }
}

export function getStoredPhccSiteName(): string {
  try {
    const user = localStorage.getItem('user');
    if (!user) {
      return '';
    }
    const parsed = JSON.parse(user);
    return parsed.custom_phcc_site_name || '';
  } catch {
    return '';
  }
}

export function persistHospitalToLocalStorage(
  customSiteName: string,
  customPhccSiteName?: string
): void {
  try {
    const storedUser = localStorage.getItem('user');
    if (!storedUser) {
      return;
    }
    const parsed = JSON.parse(storedUser);
    localStorage.setItem(
      'user',
      JSON.stringify({
        ...parsed,
        custom_site_name: customSiteName,
        ...(customPhccSiteName !== undefined
          ? { custom_phcc_site_name: customPhccSiteName }
          : {}),
      })
    );
  } catch (error) {
    console.warn('[userHospital] Failed to persist hospital to localStorage:', error);
  }
}

export async function fetchUserHospitalName(): Promise<string> {
  const filters = await fetchUserLocationFilters();
  return filters.hospital;
}

export async function fetchUserLocationFilters(): Promise<UserLocationFilters> {
  if (fetchPromise) {
    return fetchPromise;
  }

  fetchPromise = (async () => {
    try {
      const [profile, allowedHospitals, companyPerm] = await Promise.all([
        fetchCurrentUserProfile().catch(() => null),
        fetchAllowedHospitals(),
        apiService.getAllowedValues('Company').catch(() => null),
      ]);

      let hospitalName = profile?.custom_site_name || '';
      let siteName = profile?.custom_phcc_site_name || '';

      if (!hospitalName) {
        const userDetails = await apiService.getUserDetails();
        hospitalName = userDetails.custom_site_name || '';
        siteName = siteName || userDetails.custom_phcc_site_name || '';
      }

      const defaultHospital = resolveDefaultHospital(
        hospitalName,
        allowedHospitals,
        companyPerm?.default_value
      );
      const isLocked = resolveHospitalLock(allowedHospitals, hospitalName);

      if (defaultHospital) {
        cachedHospitalName = defaultHospital;
        cachedPhccSiteName = siteName;
        persistHospitalToLocalStorage(defaultHospital, siteName);
      }

      return {
        hospital: defaultHospital,
        siteName,
        isLocked,
        allowedHospitals,
      };
    } catch (error) {
      console.error('[userHospital] Failed to load user location filters:', error);
      return {
        hospital: getStoredHospitalName(),
        siteName: getStoredPhccSiteName(),
        isLocked: false,
        allowedHospitals: [],
      };
    } finally {
      fetchPromise = null;
    }
  })();

  return fetchPromise;
}

export function clearUserHospitalCache(): void {
  cachedHospitalName = null;
  cachedPhccSiteName = null;
}
