/**
 * AttendanceTakeView.tsx
 *
 * Reusable component for taking attendance in different contexts.
 */

import { useEffect, useMemo, useState } from 'react';
import {
  ClipboardCheck, Save, Users, CheckCheck, X,
  ChevronDown, AlertCircle, CheckCircle2,
} from 'lucide-react';
import api from '../store/api';
import { useAttendanceStore, AttendanceContext, AttendanceStatus, RosterRow } from '../store/attendance';
import SearchableSelect from './ui/SearchableSelect';

const todayIso = () => new Date().toISOString().split('T')[0];

const STATUS_PILL: Record<string, { label: string; bg: string; text: string; border: string }> = {
  present: { label: 'Present', bg: 'bg-emerald-500/10', text: 'text-emerald-600 dark:text-emerald-400', border: 'border-emerald-500/30' },
  absent:  { label: 'Absent',  bg: 'bg-rose-500/10',    text: 'text-rose-600 dark:text-rose-400',    border: 'border-rose-500/30' },
  excused: { label: 'Excused', bg: 'bg-amber-500/10',   text: 'text-amber-600 dark:text-amber-400',   border: 'border-amber-500/30' },
  late:    { label: 'Late',    bg: 'bg-orange-500/10',  text: 'text-orange-600 dark:text-orange-400',  border: 'border-orange-500/30' },
  'half-day': { label: 'Half-day', bg: 'bg-blue-500/10',    text: 'text-blue-600 dark:text-blue-400',    border: 'border-blue-500/30' },
};

interface ScopedPicker {
  class_id?: number;
  hostel_id?: number;
  room_id?: number;
  route_id?: number;
  club_id?: number;
}

interface AttendanceTakeViewProps {
  initialContext: AttendanceContext;
  showTabs?: boolean;
  roleFilter?: string;
}

export default function AttendanceTakeView({ initialContext, showTabs = true, roleFilter }: AttendanceTakeViewProps) {
  const { fetchRoster, submitBulkAttendance, loading, error, lastBulkResult } = useAttendanceStore();

  const [context, setContext] = useState<AttendanceContext>(initialContext);
  const [date, setDate] = useState(todayIso());
  const [picker, setPicker] = useState<ScopedPicker>({});

  // Roster rows with local state
  const [rows, setRows] = useState<RosterRow[]>([]);
  const [notes, setNotes] = useState<Record<number, string>>({});
  const [submitting, setSubmitting] = useState(false);
  const [successMsg, setSuccessMsg] = useState<string | null>(null);
  const [loadError, setLoadError] = useState<string | null>(null);

  // Dropdown sources
  const [classes, setClasses] = useState<any[]>([]);
  const [hostels, setHostels] = useState<any[]>([]);
  const [rooms, setRooms] = useState<any[]>([]);
  const [routes, setRoutes] = useState<any[]>([]);
  const [clubs, setClubs] = useState<any[]>([]);

  // Load dropdowns when tab changes
  useEffect(() => {
    setPicker({});
    setRows([]);
    setNotes({});
    if (context === 'class') {
      api.get('/classes').then(r => setClasses(r.data || [])).catch(() => setClasses([]));
    } else if (context === 'hostel') {
      api.get('/hostels').then(r => {
        const all = r.data || [];
        setHostels(all.filter((h: any) => h.occupied_count > 0));
      }).catch(() => setHostels([]));
    } else if (context === 'transport') {
      api.get('/transport/routes').then(r => setRoutes(r.data || [])).catch(() => setRoutes([]));
    } else if (context === 'club') {
      api.get('/clubs').then(r => setClubs(r.data || [])).catch(() => setClubs([]));
    }
  }, [context]);

  // Load rooms when hostel changes
  useEffect(() => {
    if (context === 'hostel' && picker.hostel_id) {
      api.get(`/hostels/${picker.hostel_id}/rooms`)
        .then(r => setRooms(r.data || []))
        .catch(() => setRooms([]));
    } else {
      setRooms([]);
    }
  }, [context, picker.hostel_id]);

  // Load roster with polling
  useEffect(() => {
    let cancelled = false;
    const loadRoster = async (isBackground = false) => {
      if (!isBackground) setLoadError(null);
      try {
        if (context === 'class') {
          if (!picker.class_id) { if (!cancelled) setRows([]); return; }
          const [studentsRes, attendanceRes] = await Promise.all([
            api.get(`/classes/${picker.class_id}/students`).catch(() => ({ data: [] })),
            api.get('/attendance', { params: { class_id: picker.class_id, date } }).catch(() => ({ data: [] })),
          ]);
          const students = Array.isArray(studentsRes.data) ? studentsRes.data : [];
          const existing = Array.isArray(attendanceRes.data) ? attendanceRes.data : [];
          const existingByStudent = new Map<number, any>();
          existing.forEach((a: any) => { if (a && a.student_id) existingByStudent.set(a.student_id, a); });
          const built: RosterRow[] = students.map((s: any) => {
            const ex = existingByStudent.get(s.id);
            return {
              student_id: s.id,
              student_name: `${s.first_name || ''} ${s.last_name || ''}`.trim() || s.name || `Student ${s.id}`,
              status: ex?.status || null,
              attendance_id: ex?.id || null,
              date: ex?.date || date,
            };
          });
          if (!cancelled) {
            setRows(prevRows => {
              const prevMap = new Map<number, RosterRow>();
              prevRows.forEach(r => prevMap.set(r.student_id, r));
              return built.map(row => {
                const prev = prevMap.get(row.student_id);
                if (prev && prev.status !== null) {
                  return { ...row, status: prev.status };
                }
                return row;
              });
            });
          }
        } else {
          // For staff, we don't need a picker (it's global), but fetchRoster needs to know
          if (context !== 'staff') {
            const idValue = context === 'hostel' ? picker.hostel_id : (context === 'transport' ? picker.route_id : picker.club_id);
            if (!idValue) { if (!cancelled) setRows([]); return; }
          }

          const rosterRes = await fetchRoster(context, {
            date,
            hostel_id: picker.hostel_id,
            room_id: picker.room_id,
            route_id: picker.route_id,
            club_id: picker.club_id,
            role: roleFilter, // Pass role filter for staff context
          });
          const fetchedRoster = rosterRes.roster || [];
          if (!cancelled) {
            setRows(prevRows => {
              const prevMap = new Map<number, RosterRow>();
              prevRows.forEach(r => prevMap.set(r.student_id, r));
              return fetchedRoster.map((row: RosterRow) => {
                const prev = prevMap.get(row.student_id);
                if (prev && prev.status !== null) {
                  return { ...row, status: prev.status };
                }
                return row;
              });
            });
          }
        }
      } catch (err: any) {
        if (!cancelled && !isBackground) setLoadError(err?.message || 'Failed to load roster');
      }
    };
    
    loadRoster();

    const interval = setInterval(() => {
        const idValue = context === 'class' ? picker.class_id : (context === 'hostel' ? picker.hostel_id : (context === 'transport' ? picker.route_id : (context === 'club' ? picker.club_id : true)));
        if (idValue) loadRoster(true);
    }, 10000);

    return () => { cancelled = true; clearInterval(interval); };
  }, [context, date, picker, fetchRoster, roleFilter]);

  const setStatus = (studentId: number, status: AttendanceStatus | null) => {
    setRows(prev => prev.map(r => r.student_id === studentId ? { ...r, status } : r));
  };

  const markAll = (status: AttendanceStatus) => {
    setRows(prev => prev.map(r => ({ ...r, status })));
  };

  const counts = useMemo(() => {
    const c = { present: 0, absent: 0, excused: 0, late: 0, halfDay: 0, unmarked: 0 };
    rows.forEach(r => {
      if (r.status === 'present') c.present++;
      else if (r.status === 'absent') c.absent++;
      else if (r.status === 'excused') c.excused++;
      else if (r.status === 'late') c.late++;
      else if (r.status === 'half-day') c.halfDay++;
      else c.unmarked++;
    });
    return c;
  }, [rows]);

  const ready = useMemo(() => {
    if (context === 'class') return !!picker.class_id;
    if (context === 'hostel') return !!picker.hostel_id;
    if (context === 'transport') return !!picker.route_id;
    if (context === 'club') return !!picker.club_id;
    if (context === 'staff') return true;
    return false;
  }, [context, picker]);

  const handleSubmit = async () => {
    if (!ready || rows.length === 0) return;
    setSubmitting(true);
    setLoadError(null);
    try {
      const records = rows
        .filter(r => r.status !== null)
        .map(r => ({ student_id: r.student_id, status: r.status as AttendanceStatus, remarks: notes[r.student_id] }));
      if (records.length === 0) {
        setLoadError('Pick a status for at least one person.');
        setSubmitting(false);
        return;
      }
      const result = await submitBulkAttendance(context, {
        date,
        class_id: picker.class_id,
        hostel_id: picker.hostel_id,
        room_id: picker.room_id,
        route_id: picker.route_id,
        club_id: picker.club_id,
        records,
      });
      if (result.success) {
        setSuccessMsg(`Saved ${result.total} records.`);
        setTimeout(() => setSuccessMsg(null), 4000);
      }
    } catch (err: any) {
      setLoadError(err?.message || 'Failed to submit');
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="space-y-8 animate-in fade-in duration-500">
      <div className="flex flex-col md:flex-row md:items-center justify-between gap-6">
        <div>
          <h2 className="text-2xl font-black text-text tracking-tight uppercase flex items-center gap-2.5">
            <ClipboardCheck className="text-primary" size={24} /> Take Attendance
          </h2>
          <p className="text-[0.65rem] font-black text-text-muted uppercase tracking-[2px] mt-0.5">Mark roll-call roster</p>
        </div>
        <div className="flex flex-wrap items-center gap-3">
          <button 
            onClick={() => markAll('present')} 
            disabled={rows.length === 0} 
            className="flex items-center gap-2 px-5 py-2.5 bg-emerald-500/10 hover:bg-emerald-500/20 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 rounded-xl font-bold text-xs uppercase tracking-wider transition-all disabled:opacity-50 disabled:pointer-events-none"
          >
            <CheckCheck size={14} /> Present All
          </button>
          <button 
            onClick={() => markAll('absent')} 
            disabled={rows.length === 0} 
            className="flex items-center gap-2 px-5 py-2.5 bg-rose-500/10 hover:bg-rose-500/20 text-rose-600 dark:text-rose-400 border border-rose-500/20 rounded-xl font-bold text-xs uppercase tracking-wider transition-all disabled:opacity-50 disabled:pointer-events-none"
          >
            <X size={14} /> Absent All
          </button>
          <button 
            onClick={handleSubmit} 
            disabled={submitting || rows.length === 0} 
            className="flex items-center gap-2 px-6 py-2.5 bg-primary text-white hover:opacity-90 rounded-xl font-bold text-xs uppercase tracking-widest transition-all disabled:opacity-50 disabled:pointer-events-none shadow-lg active:scale-95"
          >
            <Save size={14} /> {submitting ? 'Saving…' : 'Submit Roster'}
          </button>
        </div>
      </div>

      {successMsg && (
        <div className="px-6 py-3.5 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 rounded-2xl text-sm font-semibold flex items-center gap-2.5 animate-in fade-in">
          <CheckCircle2 size={18} /> {successMsg}
        </div>
      )}
      {(error || loadError) && (
        <div className="px-6 py-3.5 bg-rose-500/10 text-rose-600 dark:text-rose-400 border border-rose-500/20 rounded-2xl text-sm font-semibold flex items-center gap-2.5 animate-in fade-in">
          <AlertCircle size={18} /> {loadError || error}
        </div>
      )}

      <div className="bg-card border border-border rounded-[2.5rem] shadow-sm overflow-hidden">
        {showTabs && (
          <div className="flex flex-wrap items-center border-b border-border bg-muted/20 p-1">
            {['class', 'hostel', 'transport', 'club', 'staff'].map(t => (
              <button 
                key={t} 
                onClick={() => setContext(t as AttendanceContext)} 
                className={`px-6 py-3 rounded-xl text-[0.65rem] font-black uppercase tracking-widest transition-all ${
                  context === t 
                    ? 'bg-card text-primary shadow-sm ring-1 ring-border' 
                    : 'text-text-muted hover:text-text'
                }`}
              >
                {t}
              </button>
            ))}
          </div>
        )}

        <div className="p-6 flex flex-wrap items-center gap-4 bg-muted/20 border-b border-border">
          {context === 'class' && (
            <div className="flex items-center gap-2 min-w-[260px] flex-1">
              <SearchableSelect options={classes.map(c => ({ value: c.id, label: `${c.class_name || c.name}${c.section ? ` (${c.section})` : ''}` }))} value={picker.class_id || ''} onChange={v => setPicker(p => ({ ...p, class_id: Number(v) }))} placeholder="— select class —" className="flex-1" />
            </div>
          )}
          {context === 'hostel' && (
            <>
              <div className="flex items-center gap-2 min-w-[240px] flex-1">
                <SearchableSelect options={hostels.map(h => ({ value: h.id, label: `${h.name} (${h.type})` }))} value={picker.hostel_id || ''} onChange={v => setPicker(p => ({ ...p, hostel_id: Number(v), room_id: undefined }))} placeholder="— select hostel —" className="flex-1" />
              </div>
              <div className="flex items-center gap-2 min-w-[200px] flex-1">
                <SearchableSelect options={[{ value: '', label: '— all rooms —' }, ...rooms.map(r => ({ value: r.id, label: `Room ${r.room_number}` }))]} value={picker.room_id || ''} onChange={v => setPicker(p => ({ ...p, room_id: v ? Number(v) : undefined }))} placeholder="— all rooms —" disabled={!picker.hostel_id} className="flex-1" />
              </div>
            </>
          )}
          {context === 'transport' && (
            <div className="flex items-center gap-2 min-w-[260px] flex-1">
              <SearchableSelect options={routes.map(r => ({ value: r.id, label: r.route_title || r.name }))} value={picker.route_id || ''} onChange={v => setPicker(p => ({ ...p, route_id: Number(v) }))} placeholder="— select route —" className="flex-1" />
            </div>
          )}
          {context === 'club' && (
            <div className="flex items-center gap-2 min-w-[260px] flex-1">
              <SearchableSelect options={clubs.map(c => ({ value: c.id, label: `${c.name}${c.type ? ` (${c.type})` : ''}` }))} value={picker.club_id || ''} onChange={v => setPicker(p => ({ ...p, club_id: Number(v) }))} placeholder="— select activity —" className="flex-1" />
            </div>
          )}
          {context === 'staff' && (
            <div className="flex items-center gap-2 min-w-[260px]">
               <div className="bg-primary/10 text-primary px-4 py-2 rounded-xl text-xs font-black uppercase tracking-widest border border-primary/20">
                 Staff Roster
               </div>
            </div>
          )}
          <div className="flex items-center gap-2 ml-auto">
            <input 
              type="date" 
              value={date} 
              onChange={e => setDate(e.target.value)} 
              className="px-4 py-2 bg-background border border-border rounded-xl text-sm font-semibold text-text focus:outline-none focus:ring-4 focus:ring-primary/5 focus:border-primary transition-all" 
            />
          </div>
        </div>

        <div className="px-8 py-3.5 flex items-center gap-6 border-b border-border bg-muted/10 text-[0.65rem] font-black uppercase tracking-widest text-text-muted">
          <span>Roster: <b className="text-text font-black">{rows.length}</b></span>
          <span className="text-emerald-600 dark:text-emerald-400">Present: {counts.present}</span>
          <span className="text-rose-600 dark:text-rose-400">Absent: {counts.absent}</span>
          {context === 'staff' ? (
              <>
                <span className="text-orange-600 dark:text-orange-400">Late: {counts.late}</span>
                <span className="text-blue-600 dark:text-blue-400">Half: {counts.halfDay}</span>
              </>
          ) : (
              <span className="text-amber-600 dark:text-amber-400">Excused: {counts.excused}</span>
          )}
        </div>

        <div className="overflow-x-auto">
          <table className="w-full text-left">
            <thead>
              <tr className="bg-muted/50 border-b border-border">
                <th className="px-8 py-5 text-[0.65rem] font-black text-primary uppercase tracking-widest w-16">#</th>
                <th className="px-8 py-5 text-[0.65rem] font-black text-primary uppercase tracking-widest">{context === 'staff' ? 'Staff Member' : 'Student'}</th>
                <th className="px-8 py-5 text-[0.65rem] font-black text-primary uppercase tracking-widest text-center w-80">Status</th>
                <th className="px-8 py-5 text-[0.65rem] font-black text-primary uppercase tracking-widest">Notes</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-border">
              {loading && !rows.length ? (
                <tr>
                  <td colSpan={4} className="px-8 py-16 text-center text-text-muted font-bold uppercase tracking-widest text-xs italic">
                    Loading roster...
                  </td>
                </tr>
              ) : rows.length === 0 ? (
                <tr>
                  <td colSpan={4} className="px-8 py-16 text-center text-text-muted font-bold uppercase tracking-widest text-xs italic">
                    No {context === 'staff' ? 'staff' : 'students'} found. Pick a source above.
                  </td>
                </tr>
              ) : rows.map((r, i) => (
                <tr key={r.student_id} className="hover:bg-muted/30 transition-colors">
                  <td className="px-8 py-5 text-text-muted font-mono text-xs">{i + 1}</td>
                  <td className="px-8 py-5">
                      <div>
                          <p className="font-bold text-text text-sm">{r.student_name}</p>
                          {r.staff_role && <p className="text-[0.6rem] text-text-muted uppercase font-black mt-0.5 tracking-wider">{r.staff_role.replace('_', ' ')}</p>}
                      </div>
                  </td>
                  <td className="px-8 py-5 text-center">
                    <div className="inline-flex rounded-xl border border-border overflow-hidden bg-card p-0.5">
                      {(context === 'staff' 
                        ? ['present', 'absent', 'late', 'half-day'] 
                        : ['present', 'absent', 'excused']
                      ).map(s => (
                        <button 
                          key={s} 
                          type="button"
                          onClick={() => setStatus(r.student_id, r.status === s ? null : s as AttendanceStatus)} 
                          className={`px-4 py-2 rounded-lg text-[0.65rem] font-black uppercase transition-all whitespace-nowrap ${
                            r.status === s 
                              ? `${STATUS_PILL[s].bg} ${STATUS_PILL[s].text} shadow-sm border border-border` 
                              : 'text-text-muted hover:bg-muted border border-transparent'
                          }`}
                        >
                          {STATUS_PILL[s].label}
                        </button>
                      ))}
                    </div>
                  </td>
                  <td className="px-8 py-5">
                    <input 
                      type="text" 
                      value={notes[r.student_id] || ''} 
                      onChange={e => setNotes(prev => ({ ...prev, [r.student_id]: e.target.value }))} 
                      placeholder="Add remark..." 
                      className="w-full px-4 py-2 bg-background border border-border rounded-xl text-xs font-semibold focus:outline-none focus:border-primary focus:ring-4 focus:ring-primary/5 transition-all text-text" 
                    />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}
