// lib/facultyData.ts

export interface TeamMember {
  id: number;
  professorId: string;
  name: string;
  firstName: string;
  lastName: string;
  position: string;
  designation: string;
  image: string;
  profileUrl?: string;
  phone: string;
  email: string;
  experience: string;
  description: string;
  specialty: string;
  certification: string;
  training: string;
  workDays: string[];
  skills: Skill[];
  awards: Award[];
  status?: string;
  department?: string;
  officeLocation?: string;
  joinDate?: string;
  category: string;
  /** Controls display order within each section. Lower = earlier. */
  displayOrder: number;
}

export interface Skill {
  name: string;
  level?: number;
}

export interface Award {
  title: string;
  year: string;
  description: string;
  image: string;
}

export interface FacultyApiResponse {
  content: TeamMember[];
  last: boolean;
  first: boolean;
  totalElements: number;
  size: number;
  numberOfElements: number;
  number: number;
  empty: boolean;
}

// API service class
export class FacultyService {
  private static baseUrl =
    process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080';

  static async getAllFaculty(): Promise<TeamMember[]> {
    try {
      const timestamp = new Date().getTime();
      const response = await fetch(`${this.baseUrl}/professor?size=100&_t=${timestamp}`, {
        cache: 'no-store',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
          'Cache-Control': 'no-cache, no-store, must-revalidate',
          'Pragma': 'no-cache',
          'Expires': '0',
        },
      });

      if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);

      const data: FacultyApiResponse = await response.json();
      // The backend already orders by displayOrder ASC, lastName ASC,
      // but we sort again client-side as a safety net.
      const members = this.transformProfessorsToTeamMembers(data.content);
      return this.sortByDisplayOrder(members);
    } catch (error) {
      console.error('Error fetching faculty data:', error);
      return this.getFallbackData();
    }
  }

  static async getFacultyById(id: number | string): Promise<TeamMember | null> {
    try {
      if (typeof id === 'string' && id.includes('-')) {
        return await this.getFacultyByProfessorId(id);
      }
      const allFaculty = await this.getAllFaculty();
      return allFaculty.find(member => member.id === id) || null;
    } catch (error) {
      console.error('Error fetching faculty member:', error);
      return null;
    }
  }

  static async getFacultyByProfessorId(professorId: string): Promise<TeamMember | null> {
    try {
      const timestamp = new Date().getTime();
      const response = await fetch(`${this.baseUrl}/professor/${professorId}?_t=${timestamp}`, {
        cache: 'no-store',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
          'Cache-Control': 'no-cache, no-store, must-revalidate',
          'Pragma': 'no-cache',
          'Expires': '0',
        },
      });

      if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);

      const professor = await response.json();
      const transformed = this.transformProfessorsToTeamMembers([professor]);
      return transformed[0] || null;
    } catch (error) {
      console.error('Error fetching professor by ID:', error);
      return null;
    }
  }

  static async getFacultyByCategory(category: string): Promise<TeamMember[]> {
    try {
      const allFaculty = await this.getAllFaculty();
      return allFaculty.filter(member => member.category === category);
    } catch (error) {
      console.error('Error fetching faculty by category:', error);
      return [];
    }
  }

  static async checkImageExists(imageUrl: string): Promise<boolean> {
    try {
      const response = await fetch(imageUrl, { method: 'HEAD' });
      return response.ok;
    } catch {
      return false;
    }
  }

  static async getWorkingImageUrl(
    originalUrl: string,
    fallbackUrl: string = '/images/default-avatar.jpg'
  ): Promise<string> {
    const isAccessible = await this.checkImageExists(originalUrl);
    return isAccessible ? originalUrl : fallbackUrl;
  }

  /**
   * Sort team members by displayOrder (ascending), then lastName (alphabetical).
   * This mirrors the backend ORDER BY clause and keeps the UI deterministic.
   */
  private static sortByDisplayOrder(members: TeamMember[]): TeamMember[] {
    return [...members].sort((a, b) => {
      const orderDiff = (a.displayOrder ?? 0) - (b.displayOrder ?? 0);
      if (orderDiff !== 0) return orderDiff;
      return (a.lastName ?? '').localeCompare(b.lastName ?? '');
    });
  }

  private static transformProfessorsToTeamMembers(professors: any[]): TeamMember[] {
    return professors.map((prof, index) => {
      const imageBaseUrl = this.baseUrl;
      let imageUrl = '/images/default-avatar.jpg';

      if (prof.profileImageUrl) {
        if (prof.profileImageUrl.startsWith('http')) {
          imageUrl = prof.profileImageUrl.replace('/user/', '/professor/');
        } else {
          const relativePath = prof.profileImageUrl.replace('/user/', '/professor/');
          imageUrl = `${imageBaseUrl}${relativePath}`;
        }
      }

      const hasBackendAwards =
        prof.awards && Array.isArray(prof.awards) && prof.awards.length > 0;

      const awards = hasBackendAwards
        ? prof.awards.map((award: any) => ({
            title: award.title,
            year: award.year,
            description: award.description || '',
            image: award.imageUrl || '/images/award-icon.png',
          }))
        : [];

      return {
        id: index + 1,
        professorId: prof.professorId,
        name: prof.name || `${prof.firstName} ${prof.lastName}`,
        firstName: prof.firstName,
        lastName: prof.lastName,
        position: prof.position || 'Faculty Member',
        designation: prof.designation || prof.position || 'Faculty Member',
        image: imageUrl,
        profileUrl: `/faculty/${prof.professorId}`,
        phone: prof.phone || 'Not available',
        email: prof.email,
        experience: prof.experience || 'Not specified',
        description:
          prof.description ||
          `${prof.firstName} ${prof.lastName} is a dedicated member of our faculty.`,
        specialty: prof.specialty || prof.department || 'General Medicine',
        certification: prof.certification || 'Medical certification details not available',
        training: prof.training || 'Professional training details not available',
        workDays: prof.workDays || ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
        skills: prof.skills?.map((skill: any) => ({ name: skill.name, level: skill.level })) || [
          { name: 'Clinical Practice', level: 90 },
          { name: 'Research', level: 85 },
          { name: 'Teaching', level: 88 },
        ],
        awards,
        status: prof.status,
        department: prof.department,
        officeLocation: prof.officeLocation,
        joinDate: prof.joinDate,
        category: prof.category || 'FACULTY',
        // ← NEW: carry displayOrder through so client-side sort stays correct
        displayOrder: prof.displayOrder ?? 0,
      };
    });
  }

  private static getFallbackData(): TeamMember[] {
    return [
      {
        id: 1,
        professorId: 'fallback-1',
        name: 'Loading Faculty Data...',
        firstName: 'Loading',
        lastName: 'Data',
        position: 'Please wait while we fetch the latest faculty information',
        designation: 'System Message',
        image: '/images/default-avatar.jpg',
        profileUrl: '/faculty/fallback-1',
        phone: 'Not available',
        email: 'support@institution.edu',
        experience: 'N/A',
        description: 'Faculty data is currently being loaded from the server.',
        specialty: 'N/A',
        certification: 'N/A',
        training: 'N/A',
        workDays: [],
        skills: [],
        awards: [],
        category: 'FACULTY',
        displayOrder: 0,
      },
    ];
  }
}

export const getTeamMembers = async (): Promise<TeamMember[]> =>
  FacultyService.getAllFaculty();

export const getTeamMemberById = async (id: number | string): Promise<TeamMember | null> =>
  FacultyService.getFacultyById(id);

export const getTeamMemberByProfessorId = async (professorId: string): Promise<TeamMember | null> =>
  FacultyService.getFacultyByProfessorId(professorId);