'use client';
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { TrainingRequest } from '../app/hr/training/trainingModuleData';

interface TrainingStoreContextType {
  trainingReqs: TrainingRequest[];
  updateTrainingReqs: (updater: (prev: TrainingRequest[]) => TrainingRequest[]) => void;
  isLoading: boolean;
  refreshTrainingReqs: (employeeId?: string) => Promise<void>;
}

const TrainingStoreContext = createContext<TrainingStoreContextType | null>(null);

function mapDbToTrainingRequest(row: Record<string, unknown>): TrainingRequest {
  const fmt = (d: unknown) => {
    if (!d) return '';
    if (typeof d === 'string') return d.split('T')[0];
    return new Date(d as string).toISOString().split('T')[0];
  };
  return {
    id: row.id as string,
    employeeId: row.employeeId as string,
    employeeName: (row.employeeName as string) || (row.employeeId as string),
    dept: (row.dept as string) || '',
    courseRequested: row.courseRequested as string,
    justification: row.justification as string,
    preferredStartDate: fmt(row.preferredStartDate),
    preferredEndDate: fmt(row.preferredEndDate),
    estimatedCost: Number(row.estimatedCost) || 0,
    dateSubmitted: fmt(row.dateSubmitted),
    status: row.status as TrainingRequest['status'],
    currentStage: row.currentStage as TrainingRequest['currentStage'],
    hrApprovedBy: row.hrApprovedBy as string | undefined,
    hrApprovedOn: row.hrApprovedOn ? fmt(row.hrApprovedOn) : undefined,
    hosApprovedBy: row.hosApprovedBy as string | undefined,
    hosApprovedOn: row.hosApprovedOn ? fmt(row.hosApprovedOn) : undefined,
    financeApprovedBy: row.financeApprovedBy as string | undefined,
    financeApprovedOn: row.financeApprovedOn ? fmt(row.financeApprovedOn) : undefined,
    rejectReason: row.rejectReason as string | undefined,
    rejectedBy: row.rejectedBy as string | undefined,
    rejectedStage: row.rejectedStage as string | undefined,
    assignedProgramId: row.assignedProgramId as string | undefined,
  };
}

function mapTrainingRequestToDb(req: TrainingRequest & Record<string, unknown>) {
  return {
    id: req.id,
    employeeId: req.employeeId,
    employeeEmail: req.employeeEmail as string | undefined,
    courseRequested: req.courseRequested,
    trainingProvider: (req as Record<string, unknown>).trainingProvider || '',
    trainingMode: (req as Record<string, unknown>).trainingMode || 'Physical',
    regNo: (req as Record<string, unknown>).regNo || null,
    estimatedCost: req.estimatedCost,
    preferredStartDate: req.preferredStartDate,
    preferredEndDate: req.preferredEndDate,
    justification: req.justification,
    expectedOutcomes: (req as Record<string, unknown>).expectedOutcomes || null,
    previousTraining: (req as Record<string, unknown>).previousTraining || false,
    status: req.status,
    currentStage: req.currentStage,
    dateSubmitted: req.dateSubmitted,
    hrApprovedBy: req.hrApprovedBy || null,
    hrApprovedOn: req.hrApprovedOn || null,
    hosApprovedBy: req.hosApprovedBy || null,
    hosApprovedOn: req.hosApprovedOn || null,
    financeApprovedBy: req.financeApprovedBy || null,
    financeApprovedOn: req.financeApprovedOn || null,
    rejectReason: req.rejectReason || null,
    rejectedBy: req.rejectedBy || null,
    rejectedStage: req.rejectedStage || null,
    assignedProgramId: req.assignedProgramId || null,
  };
}

function getPersonalFetchScope(): { mine: boolean; employeeId?: string } {
  try {
    const stored = localStorage.getItem('auth_user');
    if (!stored) return { mine: false };
    const user = JSON.parse(stored);
    const personalRoles = ['employee', 'intern'];
    if (personalRoles.includes(user.role)) {
      return { mine: true, employeeId: user.employeeId || user.id };
    }
    return { mine: false };
  } catch {
    return { mine: false };
  }
}

export function TrainingStoreProvider({ children }: { children: ReactNode }) {
  const [trainingReqs, setTrainingReqs] = useState<TrainingRequest[]>([]);
  const [isLoading, setIsLoading] = useState(true);

  const refreshTrainingReqs = async (employeeId?: string) => {
    try {
      setIsLoading(true);
      const scope = employeeId ? { mine: true, employeeId } : getPersonalFetchScope();
      const url =
        scope.mine && scope.employeeId
          ? `/api/training/requests?employeeId=${encodeURIComponent(scope.employeeId)}`
          : '/api/training/requests';
      const response = await fetch(url);
      if (!response.ok) throw new Error('Failed to fetch');
      const data = await response.json();
      setTrainingReqs(data.map((r: Record<string, unknown>) => mapDbToTrainingRequest(r)));
    } catch (error) {
      console.error('Error fetching training requests:', error);
      setTrainingReqs([]);
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    refreshTrainingReqs();
  }, []);

  const updateTrainingReqs = (updater: (prev: TrainingRequest[]) => TrainingRequest[]) => {
    setTrainingReqs(prev => {
      const next = updater(prev);
      const changed = next.find(
        r =>
          !prev.some(
            p =>
              p.id === r.id &&
              p.status === r.status &&
              p.currentStage === r.currentStage
          )
      );
      const created = next.find(r => !prev.some(p => p.id === r.id));

      const record = created || changed;
      if (record) {
        const dbRecord = mapTrainingRequestToDb(record as TrainingRequest & Record<string, unknown>);
        const isExisting = prev.some(p => p.id === record.id);
        const url = isExisting ? `/api/training/requests/${record.id}` : '/api/training/requests';
        const method = isExisting ? 'PUT' : 'POST';
        fetch(url, {
          method,
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(dbRecord),
        })
          .then(res => (res.ok ? res.json() : null))
          .then(saved => {
            if (saved && created) {
              setTrainingReqs(current =>
                current.map(r => (r.id === record.id ? mapDbToTrainingRequest(saved) : r))
              );
            }
          })
          .catch(console.error);
      }
      return next;
    });
  };

  return (
    <TrainingStoreContext.Provider value={{ trainingReqs, updateTrainingReqs, isLoading, refreshTrainingReqs }}>
      {children}
    </TrainingStoreContext.Provider>
  );
}

export function useTrainingStore() {
  const ctx = useContext(TrainingStoreContext);
  if (!ctx) throw new Error('useTrainingStore must be used within TrainingStoreProvider');
  return ctx;
}
