import { createStore } from '@core/reactive-store';
import { perfMonitor } from '@core/performance-monitor';
import { DIContainer } from '@core/decorators';
import { animate, animateAll } from '@core/animation';
import { createParticles } from '@core/particles';
import { toast } from '@core/toast';
import { showModal, confirm, alert } from '@core/modal';
import { loader, buttonLoader } from '@core/loader';
import { notesManager } from '@utils/notes';
import { pomodoroTimer } from '@utils/pomodoro';
import { AttendanceCalculator, GPACalculator } from '@utils/calculators';
import '@components/student-card';



interface StudentData {
  name: string;
  attendance: Record<string, number>;
  cgpa: number;
  courses: string[];
  notices: Notice[];
  teachers: Teacher[];
  admit_card: AdmitCard;
}

interface Notice {
  id: number;
  title: string;
  date: string;
  message: string;
}

interface Teacher {
  id: number;
  name: string;
  subject: string;
  email: string;
  office: string;
}

interface AdmitCard {
  roll_number: string;
  exam_center: string;
  center_code: string;
  date_of_birth: string;
  exam_date: string;
  reporting_time: string;
  instructions: string;
}

interface AppState {
  studentId: string | null;
  studentData: StudentData | null;
  loading: boolean;
  error: string | null;
}

class APIService {
  private cache = new Map<string, { data: any; timestamp: number }>();
  private cacheDuration = 5 * 60 * 1000; // 5 minutes

  async fetch<T>(url: string, options?: RequestInit): Promise<T> {
    perfMonitor.mark(`api-start-${url}`);

    
    const cached = this.cache.get(url);
    if (cached && Date.now() - cached.timestamp < this.cacheDuration) {
      perfMonitor.measure(`api-${url}`, `api-start-${url}`);
      return cached.data;
    }

    try {
      const response = await fetch(url, options);

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

      const data = await response.json();

      
      this.cache.set(url, { data, timestamp: Date.now() });

      perfMonitor.measure(`api-${url}`, `api-start-${url}`);
      return data;
    } catch (error) {
      perfMonitor.measure(`api-${url}`, `api-start-${url}`);
      throw error;
    }
  }

  clearCache(): void {
    this.cache.clear();
  }
}



DIContainer.register('apiService', () => new APIService());



const store = createStore<AppState>({
  studentId: null,
  studentData: null,
  loading: false,
  error: null
}, {
  persistKey: 'student-portal-state',
  devTools: import.meta.env.DEV
});


store.defineComputed('hasStudent', (state) => state.studentId !== null);
store.defineComputed('attendanceAverage', (state) => {
  if (!state.studentData?.attendance) return 0;
  const values = Object.values(state.studentData.attendance);
  return values.reduce((a, b) => a + b, 0) / values.length;
});


class PageController {
  protected studentId: string;
  protected apiService: APIService;

  constructor(studentId: string) {
    this.studentId = studentId;
    this.apiService = DIContainer.resolve('apiService');
  }
}

class CGPAController extends PageController {
  async initialize() {
    const page = document.getElementById('cgpa-page');
    if (!page) return;

    const cgpaEl = document.getElementById('cgpaValue');
    const refreshBtn = document.getElementById('refreshCgpa');

    if (!cgpaEl || !refreshBtn) return;

    const loadCGPA = async () => {
      perfMonitor.mark('load-cgpa-start');

      try {
        store.setState({ loading: true, error: null });
        const data = await this.apiService.fetch<{ cgpa: number }>(`/api/student/${this.studentId}/cgpa`);

        cgpaEl.textContent = data.cgpa.toFixed(2);
        store.setState({ loading: false });

        perfMonitor.measure('load-cgpa', 'load-cgpa-start');
      } catch (error) {
        console.error(error);
        cgpaEl.textContent = 'Failed to load';
        store.setState({ loading: false, error: 'Failed to load CGPA' });
      }
    };

    refreshBtn.addEventListener('click', () => {
      cgpaEl.style.opacity = '0.6';
      loadCGPA().finally(() => {
        cgpaEl.style.opacity = '1';
      });
    });

    await loadCGPA();
  }
}

class AttendanceController extends PageController {
  async initialize() {
    const page = document.getElementById('attendance-page');
    if (!page) return;

    const listEl = document.getElementById('attendanceList');
    const refreshBtn = document.getElementById('refreshAttendance');

    if (!listEl || !refreshBtn) return;

    const loadAttendance = async () => {
      perfMonitor.mark('load-attendance-start');

      try {
        store.setState({ loading: true });
        const data = await this.apiService.fetch<{ attendance: Record<string, number> }>(
          `/api/student/${this.studentId}/attendance`
        );

        listEl.innerHTML = '';

        if (!data.attendance || Object.keys(data.attendance).length === 0) {
          listEl.innerHTML = '<p style="color: rgba(255, 255, 255, 0.6); text-align: center;">No attendance records</p>';
          return;
        }

        Object.entries(data.attendance).forEach(([course, percent]) => {
          const div = this.createAttendanceCard(course, percent);
          listEl.appendChild(div);
        });

        store.setState({ loading: false });
        perfMonitor.measure('load-attendance', 'load-attendance-start');
      } catch (error) {
        console.error(error);
        listEl.innerHTML = '<p style="color: red;">Failed to load attendance</p>';
        store.setState({ loading: false, error: 'Failed to load attendance' });
      }
    };

    refreshBtn.addEventListener('click', () => {
      listEl.style.opacity = '0.6';
      loadAttendance().finally(() => {
        listEl.style.opacity = '1';
      });
    });

    await loadAttendance();
  }

  private createAttendanceCard(course: string, percent: number): HTMLElement {
    const div = document.createElement('div');
    const borderColor = percent >= 75 ? '#4caf50' : percent >= 60 ? '#ffc107' : '#f44336';

    div.className = 'attendance-card';
    div.style.cssText = `
      background: rgba(255,255,255,0.1);
      border: 1px solid rgba(255,255,255,0.2);
      border-left: 4px solid ${borderColor};
      padding: 1.2rem;
      margin-bottom: 0.75rem;
      border-radius: 10px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      transition: all 0.3s ease;
    `;

    div.onmouseenter = () => {
      div.style.background = 'rgba(255,255,255,0.15)';
      div.style.transform = 'translateX(5px)';
    };

    div.onmouseleave = () => {
      div.style.background = 'rgba(255,255,255,0.1)';
      div.style.transform = 'translateX(0)';
    };

    const courseEl = document.createElement('span');
    courseEl.textContent = course;
    courseEl.style.cssText = 'color: white; font-weight: 600; font-size: 1.05rem;';

    const percentEl = document.createElement('span');
    percentEl.textContent = `${percent}%`;
    percentEl.style.cssText = `
      background: linear-gradient(135deg, #667eea, #764ba2);
      padding: 0.6rem 1.2rem;
      border-radius: 20px;
      color: white;
      font-weight: 700;
      font-size: 1.1rem;
    `;

    div.appendChild(courseEl);
    div.appendChild(percentEl);

    return div;
  }
}



class Application {
  private controllers = new Map<string, PageController>();

  async initialize() {
    perfMonitor.mark('app-init-start');

    
    if (import.meta.env.DEV) {
      perfMonitor.showOverlay();
    }

    this.initializeControllers();


    if ('serviceWorker' in navigator && import.meta.env.PROD) {
      try {
        await navigator.serviceWorker.register('/sw.js');
      } catch (error) {
        console.error('Service Worker registration failed:', error);
      }
    }

    perfMonitor.measure('app-init', 'app-init-start');
  }

  private initializeControllers() {
    const cgpaPage = document.getElementById('cgpa-page');
    const attendancePage = document.getElementById('attendance-page');

    if (cgpaPage) {
      const studentId = cgpaPage.dataset.studentId!;
      const controller = new CGPAController(studentId);
      this.controllers.set('cgpa', controller);
      controller.initialize();
    }

    if (attendancePage) {
      const studentId = attendancePage.dataset.studentId!;
      const controller = new AttendanceController(studentId);
      this.controllers.set('attendance', controller);
      controller.initialize();
    }
  }

  getStore() {
    return store;
  }

  getPerformanceMetrics() {
    return perfMonitor.getMetrics();
  }
}

function createUtilitiesMenu() {
  const menuBtn = document.createElement('button');
  menuBtn.id = 'utilities-menu-btn';
  menuBtn.innerHTML = '🛠️';
  menuBtn.setAttribute('aria-label', 'Student Utilities');
  menuBtn.style.cssText = `
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: linear-gradient(135deg, #667eea, #764ba2);
    border: none;
    color: white;
    font-size: 28px;
    cursor: pointer;
    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
    z-index: 9997;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    display: flex;
    align-items: center;
    justify-content: center;
  `;

  menuBtn.addEventListener('mouseenter', () => {
    menuBtn.style.transform = 'scale(1.1) rotate(15deg)';
    menuBtn.style.boxShadow = '0 12px 32px rgba(102, 126, 234, 0.6)';
  });

  menuBtn.addEventListener('mouseleave', () => {
    menuBtn.style.transform = 'scale(1) rotate(0deg)';
    menuBtn.style.boxShadow = '0 8px 24px rgba(102, 126, 234, 0.4)';
  });

  menuBtn.addEventListener('click', () => {
    showModal({
      title: '🛠️ Student Utilities',
      content: createUtilitiesContent(),
      width: '700px',
      animation: 'scale'
    });
  });

  document.body.appendChild(menuBtn);
}

function createUtilitiesContent(): HTMLElement {
  const container = document.createElement('div');
  container.style.cssText = 'padding: 20px;';

  const utilities = [
    {
      icon: '📊',
      title: 'Attendance Calculator',
      description: 'Calculate how many classes you need to attend or can skip',
      onClick: () => AttendanceCalculator.showCalculator()
    },
    {
      icon: '🎓',
      title: 'GPA Calculator',
      description: 'Calculate your GPA based on grades and credits',
      onClick: () => GPACalculator.showCalculator()
    },
    {
      icon: '⏱️',
      title: 'Pomodoro Timer',
      description: 'Focus on your studies with the Pomodoro technique',
      onClick: () => {
        pomodoroTimer.createWidget();
        toast.info('Pomodoro timer widget added!', 'Timer Ready');
      }
    },
    {
      icon: '📝',
      title: 'Quick Notes',
      description: 'Create sticky notes for quick reminders',
      onClick: () => {
        notesManager.createFloatingButton();
        toast.info('Notes button added! Click to create notes.', 'Notes Ready');
      }
    },
  ];

  utilities.forEach(util => {
    const card = document.createElement('div');
    card.style.cssText = `
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid rgba(255, 255, 255, 0.1);
      border-radius: 12px;
      padding: 20px;
      margin-bottom: 16px;
      cursor: pointer;
      transition: all 0.3s ease;
      display: flex;
      align-items: center;
      gap: 16px;
    `;

    card.addEventListener('mouseenter', () => {
      card.style.background = 'rgba(255, 255, 255, 0.1)';
      card.style.transform = 'translateX(8px)';
      card.style.borderColor = 'rgba(102, 126, 234, 0.5)';
    });

    card.addEventListener('mouseleave', () => {
      card.style.background = 'rgba(255, 255, 255, 0.05)';
      card.style.transform = 'translateX(0)';
      card.style.borderColor = 'rgba(255, 255, 255, 0.1)';
    });

    card.addEventListener('click', util.onClick);

    const iconEl = document.createElement('div');
    iconEl.textContent = util.icon;
    iconEl.style.cssText = `
      font-size: 48px;
      width: 64px;
      height: 64px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: rgba(102, 126, 234, 0.2);
      border-radius: 12px;
      flex-shrink: 0;
    `;

    const contentEl = document.createElement('div');
    contentEl.style.cssText = 'flex: 1;';

    const titleEl = document.createElement('div');
    titleEl.textContent = util.title;
    titleEl.style.cssText = `
      font-size: 18px;
      font-weight: 700;
      color: white;
      margin-bottom: 4px;
    `;

    const descEl = document.createElement('div');
    descEl.textContent = util.description;
    descEl.style.cssText = `
      font-size: 14px;
      color: rgba(255, 255, 255, 0.7);
      line-height: 1.5;
    `;

    contentEl.appendChild(titleEl);
    contentEl.appendChild(descEl);

    card.appendChild(iconEl);
    card.appendChild(contentEl);
    container.appendChild(card);
  });

  return container;
}

document.addEventListener('DOMContentLoaded', async () => {
  
  createParticles(document.body, {
    count: 60,
    speed: 0.3,
    size: 2,
    color: 'rgba(102, 126, 234, 0.5)',
    connectDistance: 100,
    mouseRadius: 180,
    interactive: true
  });

  const app = new Application();
  await app.initialize();

  createUtilitiesMenu();

  setTimeout(() => {
    animateAll('.card, .stat-card, .btn', {
      opacity: 1,
      transform: 'translateY(0)'
    }, {
      duration: 600,
      easing: 'easeOutCubic',
      stagger: 100
    });
  }, 500);
  // Expose essential tools globally for use in templates
  (window as any).__APP__ = app;
  (window as any).__STORE__ = store;
  (window as any).__TOAST__ = toast;
  (window as any).__MODAL__ = showModal;
  (window as any).__LOADER__ = loader;
});

if (import.meta.hot) {
  import.meta.hot.accept();
}
