import { create } from 'zustand';
import type { Student, StudentFormData } from '@/types';
import { calculateAge, generateStudentId, generatePassword } from '@/lib/formatters';
import { studentsApi } from '@/lib/apiClient';

interface StudentState {
  students: Student[];
  selectedStudent: Student | null;
  filters: { search: string; batch: string; skillLevel: string; status: string };
  isLoading: boolean;
  lastId: number;
  getFilteredStudents: () => Student[];
  selectStudent: (id: number) => void;
  fetchStudents: () => Promise<void>;
  addStudent: (data: StudentFormData) => Promise<{ studentId: string; password: string }>;
  updateStudent: (id: number, data: Partial<StudentFormData>) => Promise<void>;
  deleteStudent: (id: number) => Promise<void>;
  toggleFeeStatus: (id: number) => Promise<void>;
  setFilters: (filters: Partial<StudentState['filters']>) => void;
}

// No demo data - starts empty for real data import
const demoStudents: Student[] = [];

// Map API response to Student type
function mapApiStudent(s: Record<string, unknown>): Student {
  return {
    id: Number(s.id ?? 0),
    studentId: String(s.student_id ?? s.studentId ?? ''),
    fullName: String(s.full_name ?? s.fullName ?? ''),
    dateOfBirth: String(s.date_of_birth ?? s.dateOfBirth ?? ''),
    gender: (s.gender as 'male' | 'female' | 'other') ?? 'male',
    phone: String(s.phone ?? ''),
    email: String(s.email ?? ''),
    guardianName: String(s.guardian_name ?? s.guardianName ?? ''),
    guardianPhone: String(s.guardian_phone ?? s.guardianPhone ?? ''),
    guardianRelationship: (s.guardian_relationship ?? s.guardianRelationship ?? 'parent') as 'parent' | 'sibling' | 'other',
    batchId: Number(s.batch_id ?? s.batchId ?? 1),
    batchName: String(s.batch_name ?? s.batchName ?? ''),
    skillLevel: (s.skill_level ?? s.skillLevel ?? 'beginner') as 'beginner' | 'intermediate' | 'advanced',
    monthlyFee: Number(s.monthly_fee ?? s.monthlyFee ?? 1500),
    joiningDate: String(s.joining_date ?? s.joiningDate ?? ''),
    isActive: Boolean(s.is_active ?? s.isActive ?? 1),
    age: s.date_of_birth ? calculateAge(String(s.date_of_birth)) : (s.age ? Number(s.age) : 0),
    feeStatus: (s.fee_status ?? s.feeStatus ?? 'pending') as 'paid' | 'due' | 'pending',
  };
}

export const useStudentStore = create<StudentState>((set, get) => ({
  students: [],
  selectedStudent: null,
  filters: { search: '', batch: '', skillLevel: '', status: '' },
  isLoading: false,
  lastId: 8,

  getFilteredStudents: () => {
    const { students, filters } = get();
    return students.filter(s => {
      if (filters.search && !s.fullName.toLowerCase().includes(filters.search.toLowerCase()) && !s.studentId.toLowerCase().includes(filters.search.toLowerCase())) return false;
      if (filters.batch && s.batchName !== filters.batch) return false;
      if (filters.skillLevel && s.skillLevel !== filters.skillLevel) return false;
      if (filters.status && s.feeStatus !== filters.status) return false;
      return true;
    });
  },

  selectStudent: (id) => {
    const student = get().students.find(s => s.id === id) || null;
    set({ selectedStudent: student });
  },

  fetchStudents: async () => {
    try {
      const data = await studentsApi.getAll();
      if (Array.isArray(data)) {
        const mapped = data.map(mapApiStudent);
        set({ students: mapped, lastId: mapped.length > 0 ? Math.max(...mapped.map(s => s.id)) : 0 });
      }
    } catch {
      // Fallback to demo data if API not available
      set({ students: demoStudents, lastId: 8 });
    }
  },

  addStudent: async (data) => {
    await new Promise(r => setTimeout(r, 600));
    try {
      const result = await studentsApi.create(data as unknown as Record<string, unknown>);
      if (result.success) {
        // Refresh student list
        await get().fetchStudents();
        return { studentId: result.studentId ?? '', password: result.password ?? '' };
      }
    } catch {
      // Offline fallback
    }
    // Local fallback
    const state = get();
    const newId = state.lastId + 1;
    const studentId = generateStudentId(state.lastId);
    const password = generatePassword(data.fullName, data.phone);

    const newStudent: Student = {
      id: newId,
      studentId,
      fullName: data.fullName,
      dateOfBirth: data.dateOfBirth,
      gender: data.gender,
      phone: data.phone,
      email: data.email,
      address: data.address,
      guardianName: data.guardianName,
      guardianPhone: data.guardianPhone,
      guardianRelationship: data.guardianRelationship,
      batchId: data.batchId,
      skillLevel: data.skillLevel,
      monthlyFee: data.monthlyFee,
      joiningDate: data.joiningDate,
      isActive: true,
      age: calculateAge(data.dateOfBirth),
      feeStatus: 'pending',
    };
    set({ students: [...state.students, newStudent], lastId: newId });
    return { studentId, password };
  },

  updateStudent: async (id, data) => {
    try {
      await studentsApi.update(id, data as unknown as Record<string, unknown>);
      await get().fetchStudents();
    } catch {
      // Offline fallback
      set(state => ({
        students: state.students.map(s => s.id === id ? { ...s, ...data, age: data.dateOfBirth ? calculateAge(data.dateOfBirth) : s.age } : s),
      }));
    }
  },

  deleteStudent: async (id) => {
    try {
      await studentsApi.delete(id);
      await get().fetchStudents();
    } catch {
      // Offline fallback
      set(state => ({
        students: state.students.map(s => s.id === id ? { ...s, isActive: false } : s),
      }));
    }
  },

  toggleFeeStatus: async (id) => {
    const student = get().students.find(s => s.id === id);
    if (!student) return;
    const newStatus = student.feeStatus === 'paid' ? 'due' : 'paid';
    try {
      await studentsApi.update(id, { feeStatus: newStatus });
      await get().fetchStudents();
    } catch {
      // Offline fallback
      set(state => ({
        students: state.students.map(s =>
          s.id === id ? { ...s, feeStatus: s.feeStatus === 'paid' ? 'due' as const : 'paid' as const } : s
        ),
        selectedStudent: state.selectedStudent?.id === id
          ? { ...state.selectedStudent, feeStatus: state.selectedStudent.feeStatus === 'paid' ? 'due' as const : 'paid' as const }
          : state.selectedStudent,
      }));
    }
  },

  setFilters: (filters) => set(state => ({ filters: { ...state.filters, ...filters } })),
}));
