import React, { createContext, useContext, useState, ReactNode, useEffect } from "react";
import { useAuth } from "./AuthContext";
import { getPendingUsers, approveUser as apiApproveUser, getProfessionals, assignProfessional as apiAssignProfessional, removeProfessional as apiRemoveProfessional, updateEventStatus as apiUpdateStatus, updateAssignmentStatus as apiUpdateAssignmentStatus, updateAgenda as apiUpdateAgenda } from "../services/apiService";
import {
  EventData,
  EventStatus,
  EventType,
  Institution,
  Course,
  User,
  UserApprovalStatus,
  UserRole,
  Professional,
} from "../types";

// Initial Mock Data
const INITIAL_INSTITUTIONS: Institution[] = [
  {
    id: "inst-1",
    name: "Universidade Federal do Rio Grande do Sul",
    type: "Universidade Pública",
    phone: "(51) 3308-3333",
    email: "eventos@ufrgs.br",
    address: {
      street: "Av. Paulo Gama",
      number: "110",
      city: "Porto Alegre",
      state: "RS",
      zip: "90040-060",
    },
    description:
      "Campus Central - Principais eventos realizados no Salão de Atos",
    ownerId: "client-1",
  },
];

const INITIAL_EVENTS: EventData[] = [
  {
    id: "1",
    name: "Formatura Engenharia Civil",
    date: "2025-12-05",
    time: "19:00",
    type: EventType.GRADUATION,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Av. das Hortênsias",
      number: "1200",
      city: "Gramado",
      state: "RS",
      zip: "95670-000",
    },
    briefing:
      "Cerimônia de formatura com 120 formandos. Foco em fotos individuais e da turma.",
    coverImage: "https://picsum.photos/id/1059/800/400",
    contacts: [
      {
        id: "c1",
        name: "Comissão de Formatura",
        role: "Organizador",
        phone: "51 99999-1111",
        email: "formatura@email.com",
      },
    ],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-1", "photographer-2"],
    institutionId: "inst-1",
  },
  {
    id: "2",
    name: "Colação de Grau Medicina",
    date: "2025-12-05",
    time: "10:00",
    type: EventType.COLATION,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Rua Olimpíadas",
      number: "205",
      city: "São Paulo",
      state: "SP",
      zip: "04551-000",
    },
    briefing:
      "Colação de grau solene. Capturar juramento e entrega de diplomas.",
    coverImage: "https://picsum.photos/id/3/800/400",
    contacts: [
      {
        id: "c2",
        name: "Secretaria Acadêmica",
        role: "Coordenador",
        phone: "11 98888-2222",
        email: "academico@med.br",
      },
    ],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-1"],
  },
  {
    id: "3",
    name: "Semana Acadêmica Direito",
    date: "2025-12-05",
    time: "14:00",
    type: EventType.ACADEMIC_WEEK,
    status: EventStatus.IN_PROGRESS,
    address: {
      street: "Av. Paulista",
      number: "1500",
      city: "São Paulo",
      state: "SP",
      zip: "01310-100",
    },
    briefing: "Palestras e painéis durante toda a semana. Cobertura de 3 dias.",
    coverImage: "https://picsum.photos/id/10/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-2",
    photographerIds: ["photographer-2"],
  },
  {
    id: "4",
    name: "Defesa de Doutorado - Maria Silva",
    date: "2025-12-05",
    time: "15:30",
    type: EventType.DEFENSE,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Rua Ramiro Barcelos",
      number: "2600",
      city: "Porto Alegre",
      state: "RS",
      zip: "90035-003",
    },
    briefing:
      "Defesa de tese em sala fechada. Fotos discretas da apresentação e banca.",
    coverImage: "https://picsum.photos/id/20/800/400",
    contacts: [
      {
        id: "c3",
        name: "Prof. João Santos",
        role: "Orientador",
        phone: "51 97777-3333",
        email: "joao@univ.br",
      },
    ],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-1"],
  },
  {
    id: "5",
    name: "Semana de Calouros 2026",
    date: "2025-12-06",
    time: "09:00",
    type: EventType.FRESHMAN_WEEK,
    status: EventStatus.PENDING_APPROVAL,
    address: {
      street: "Campus Universitário",
      number: "s/n",
      city: "Curitiba",
      state: "PR",
      zip: "80060-000",
    },
    briefing: "Recepção dos calouros com atividades de integração e gincanas.",
    coverImage: "https://picsum.photos/id/30/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-2",
    photographerIds: [],
  },
  {
    id: "6",
    name: "Formatura Administração",
    date: "2025-12-06",
    time: "20:00",
    type: EventType.GRADUATION,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Av. Ipiranga",
      number: "6681",
      city: "Porto Alegre",
      state: "RS",
      zip: "90619-900",
    },
    briefing: "Formatura noturna com jantar. Fotos da cerimônia e festa.",
    coverImage: "https://picsum.photos/id/40/800/400",
    contacts: [
      {
        id: "c4",
        name: "Lucas Oliveira",
        role: "Presidente da Comissão",
        phone: "51 96666-4444",
        email: "lucas@formatura.com",
      },
    ],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-2"],
  },
  {
    id: "7",
    name: "Congresso de Tecnologia",
    date: "2025-12-06",
    time: "08:30",
    type: EventType.SYMPOSIUM,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Av. das Nações Unidas",
      number: "12901",
      city: "São Paulo",
      state: "SP",
      zip: "04578-000",
    },
    briefing:
      "Congresso com múltiplas salas. Cobrir palestrantes principais e stands.",
    coverImage: "https://picsum.photos/id/50/800/400",
    contacts: [
      {
        id: "c5",
        name: "Eventos Tech",
        role: "Organizadora",
        phone: "11 95555-5555",
        email: "contato@eventostech.com",
      },
    ],
    checklist: [],
    ownerId: "client-2",
    photographerIds: ["photographer-1", "photographer-3"],
  },
  {
    id: "8",
    name: "Campeonato Universitário de Futsal",
    date: "2025-12-06",
    time: "16:00",
    type: EventType.SPORTS_EVENT,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Rua dos Esportes",
      number: "500",
      city: "Gramado",
      state: "RS",
      zip: "95670-100",
    },
    briefing: "Final do campeonato. Fotos dinâmicas da partida e premiação.",
    coverImage: "https://picsum.photos/id/60/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-3"],
  },
  {
    id: "9",
    name: "Colação de Grau Odontologia",
    date: "2025-12-07",
    time: "11:00",
    type: EventType.COLATION,
    status: EventStatus.PLANNING,
    address: {
      street: "Rua Voluntários da Pátria",
      number: "89",
      city: "Porto Alegre",
      state: "RS",
      zip: "90230-010",
    },
    briefing: "Cerimônia formal de colação. Fotos individuais e em grupo.",
    coverImage: "https://picsum.photos/id/70/800/400",
    contacts: [
      {
        id: "c6",
        name: "Direção da Faculdade",
        role: "Coordenador",
        phone: "51 94444-6666",
        email: "direcao@odonto.edu",
      },
    ],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-2"],
  },
  {
    id: "10",
    name: "Festival Cultural Universitário",
    date: "2025-12-07",
    time: "18:00",
    type: EventType.CULTURAL_EVENT,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Praça da República",
      number: "s/n",
      city: "São Paulo",
      state: "SP",
      zip: "01045-000",
    },
    briefing:
      "Festival com apresentações musicais e teatrais. Cobertura completa.",
    coverImage: "https://picsum.photos/id/80/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-2",
    photographerIds: ["photographer-1"],
  },
  {
    id: "11",
    name: "Defesa de Mestrado - Pedro Costa",
    date: "2025-12-07",
    time: "14:00",
    type: EventType.DEFENSE,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Av. Bento Gonçalves",
      number: "9500",
      city: "Porto Alegre",
      state: "RS",
      zip: "91509-900",
    },
    briefing:
      "Defesa de dissertação. Registro da apresentação e momento da aprovação.",
    coverImage: "https://picsum.photos/id/90/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-3"],
  },
  {
    id: "12",
    name: "Formatura Psicologia",
    date: "2025-12-08",
    time: "19:30",
    type: EventType.GRADUATION,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Av. Protásio Alves",
      number: "7000",
      city: "Porto Alegre",
      state: "RS",
      zip: "91310-000",
    },
    briefing: "Formatura emotiva com homenagens. Foco em momentos especiais.",
    coverImage: "https://picsum.photos/id/100/800/400",
    contacts: [
      {
        id: "c7",
        name: "Ana Paula",
        role: "Formanda",
        phone: "51 93333-7777",
        email: "ana@email.com",
      },
    ],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-1", "photographer-2"],
  },
  {
    id: "13",
    name: "Simpósio de Engenharia",
    date: "2025-12-08",
    time: "09:00",
    type: EventType.SYMPOSIUM,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Av. Sertório",
      number: "6600",
      city: "Porto Alegre",
      state: "RS",
      zip: "91040-000",
    },
    briefing: "Apresentações técnicas e workshops. Cobrir painéis principais.",
    coverImage: "https://picsum.photos/id/110/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-2"],
  },
  {
    id: "14",
    name: "Torneio de Vôlei Universitário",
    date: "2025-12-08",
    time: "15:00",
    type: EventType.SPORTS_EVENT,
    status: EventStatus.IN_PROGRESS,
    address: {
      street: "Rua Faria Santos",
      number: "100",
      city: "Curitiba",
      state: "PR",
      zip: "80060-150",
    },
    briefing: "Semifinais e final. Fotos de ação e torcida.",
    coverImage: "https://picsum.photos/id/120/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-2",
    photographerIds: ["photographer-3"],
  },
  {
    id: "15",
    name: "Colação de Grau Enfermagem",
    date: "2025-12-09",
    time: "10:30",
    type: EventType.COLATION,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Rua São Manoel",
      number: "963",
      city: "São Paulo",
      state: "SP",
      zip: "01330-001",
    },
    briefing: "Colação com juramento de Florence Nightingale. Momento solene.",
    coverImage: "https://picsum.photos/id/130/800/400",
    contacts: [
      {
        id: "c8",
        name: "Coordenação de Enfermagem",
        role: "Coordenador",
        phone: "11 92222-8888",
        email: "coord@enf.br",
      },
    ],
    checklist: [],
    ownerId: "client-2",
    photographerIds: ["photographer-1"],
  },
  {
    id: "16",
    name: "Semana Acadêmica Biomedicina",
    date: "2025-12-09",
    time: "13:00",
    type: EventType.ACADEMIC_WEEK,
    status: EventStatus.PLANNING,
    address: {
      street: "Av. Independência",
      number: "2293",
      city: "Porto Alegre",
      state: "RS",
      zip: "90035-075",
    },
    briefing: "Palestras e atividades práticas. Cobertura de 2 dias.",
    coverImage: "https://picsum.photos/id/140/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-1",
    photographerIds: [],
  },
  {
    id: "17",
    name: "Formatura Ciências Contábeis",
    date: "2025-12-09",
    time: "20:30",
    type: EventType.GRADUATION,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Av. das Américas",
      number: "3500",
      city: "Gramado",
      state: "RS",
      zip: "95670-200",
    },
    briefing:
      "Formatura elegante em hotel. Cobertura completa da cerimônia e recepção.",
    coverImage: "https://picsum.photos/id/150/800/400",
    contacts: [
      {
        id: "c9",
        name: "Rodrigo Almeida",
        role: "Tesoureiro",
        phone: "51 91111-9999",
        email: "rodrigo@turma.com",
      },
    ],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-2", "photographer-3"],
  },
  {
    id: "18",
    name: "Defesa de TCC - Turma 2025",
    date: "2025-12-09",
    time: "16:30",
    type: EventType.DEFENSE,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Rua Marquês do Pombal",
      number: "2000",
      city: "Porto Alegre",
      state: "RS",
      zip: "90540-000",
    },
    briefing:
      "Múltiplas defesas sequenciais. Fotos rápidas de cada apresentação.",
    coverImage: "https://picsum.photos/id/160/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-1"],
  },
  {
    id: "19",
    name: "Festival de Música Universitária",
    date: "2025-12-10",
    time: "19:00",
    type: EventType.CULTURAL_EVENT,
    status: EventStatus.PENDING_APPROVAL,
    address: {
      street: "Parque da Redenção",
      number: "s/n",
      city: "Porto Alegre",
      state: "RS",
      zip: "90040-000",
    },
    briefing:
      "Festival ao ar livre com várias bandas. Fotos de palco e público.",
    coverImage: "https://picsum.photos/id/170/800/400",
    contacts: [],
    checklist: [],
    ownerId: "client-2",
    photographerIds: [],
  },
  {
    id: "20",
    name: "Colação de Grau Arquitetura",
    date: "2025-12-10",
    time: "11:30",
    type: EventType.COLATION,
    status: EventStatus.CONFIRMED,
    address: {
      street: "Av. Borges de Medeiros",
      number: "1501",
      city: "Gramado",
      state: "RS",
      zip: "95670-300",
    },
    briefing: "Cerimônia especial com exposição de projetos. Fotos criativas.",
    coverImage: "https://picsum.photos/id/180/800/400",
    contacts: [
      {
        id: "c10",
        name: "Atelier Arquitetura",
        role: "Escritório Parceiro",
        phone: "51 90000-1010",
        email: "contato@atelier.arq",
      },
    ],
    checklist: [],
    ownerId: "client-1",
    photographerIds: ["photographer-3"],
  },
];

// Initial Mock Courses
const INITIAL_COURSES: Course[] = [
  {
    id: "course-1",
    name: "Engenharia Civil 2025",
    institutionId: "inst-1",
    year: 2025,
    semester: 2,
    graduationType: "Bacharelado",
    createdAt: new Date().toISOString(),
    createdBy: "admin-1",
    isActive: true,
  },
  {
    id: "course-2",
    name: "Medicina - Turma A 2025",
    institutionId: "inst-1",
    year: 2025,
    semester: 1,
    graduationType: "Bacharelado",
    createdAt: new Date().toISOString(),
    createdBy: "admin-1",
    isActive: true,
  },
  {
    id: "course-3",
    name: "Direito Noturno 2025",
    institutionId: "inst-1",
    year: 2025,
    semester: 2,
    graduationType: "Bacharelado",
    createdAt: new Date().toISOString(),
    createdBy: "admin-1",
    isActive: true,
  },
];

interface DataContextType {
  events: EventData[];
  institutions: Institution[];
  courses: Course[];
  pendingUsers: User[];
  addEvent: (event: EventData) => void;
  updateEventStatus: (id: string, status: EventStatus) => void;
  assignPhotographer: (eventId: string, photographerId: string) => void;
  getEventsByRole: (userId: string, role: string) => EventData[];
  addInstitution: (institution: Institution) => void;
  updateInstitution: (id: string, institution: Partial<Institution>) => void;
  getInstitutionsByUserId: (userId: string) => Institution[];
  getInstitutionById: (id: string) => Institution | undefined;
  addCourse: (course: Course) => void;
  updateCourse: (id: string, course: Partial<Course>) => void;
  getCoursesByInstitutionId: (institutionId: string) => Course[];
  getActiveCoursesByInstitutionId: (institutionId: string) => Course[];
  getCourseById: (id: string) => Course | undefined;
  registerPendingUser: (userData: { id: string; name: string; email: string; phone: string; registeredInstitution?: string }) => void;

  approveUser: (userId: string) => void;
  rejectUser: (userId: string) => void;
  professionals: Professional[];
  respondToAssignment: (eventId: string, status: string, reason?: string) => Promise<void>;
  updateEventDetails: (id: string, data: any) => Promise<void>;
  functions: { id: string; nome: string }[];
  isLoading: boolean;
  refreshEvents: () => Promise<void>;
}

const DataContext = createContext<DataContextType | undefined>(undefined);


export const DataProvider: React.FC<{ children: ReactNode }> = ({
  children,
}) => {
  const { token, user } = useAuth(); // Consume Auth Context
  const [events, setEvents] = useState<EventData[]>([]);
  const [institutions, setInstitutions] =
    useState<Institution[]>(INITIAL_INSTITUTIONS);
  const [courses, setCourses] = useState<Course[]>(INITIAL_COURSES);
  
  const [isLoading, setIsLoading] = useState<boolean>(false);

  const [pendingUsers, setPendingUsers] = useState<User[]>([]);
  const [professionals, setProfessionals] = useState<Professional[]>([]);
  const [functions, setFunctions] = useState<{ id: string; nome: string }[]>([]);
  const [refreshTrigger, setRefreshTrigger] = useState(0);

  // Fetch events from API
  useEffect(() => {
    const fetchEvents = async () => {
      // Use token from context or fallback to localStorage if context not ready (though context is preferred sources of truth)
      const visibleToken = token || localStorage.getItem("token");

      if (visibleToken) {
        setIsLoading(true);
        try {
          // Import dynamic to avoid circular dependency if any, or just use imported service
          const { getAgendas, getFunctions } = await import("../services/apiService");
          
          // Fetch Functions (Roles)
          getFunctions().then(res => {
            if (res.data) setFunctions(res.data);
          });

          const result = await getAgendas(visibleToken);
          console.log("Raw Agenda Data:", result.data); // Debug logging
          if (result.data) {
            console.log("Sample event from backend:", result.data[0]); // DEBUG: Ver estrutura e status

            // Map backend status to frontend EventStatus
            const mapStatus = (backendStatus: string): EventStatus => {
              const statusMap: Record<string, EventStatus> = {
                "Pendente": EventStatus.PENDING_APPROVAL,
                "Aguardando Aprovação": EventStatus.PENDING_APPROVAL,
                "PENDING_APPROVAL": EventStatus.PENDING_APPROVAL,
                "Confirmado": EventStatus.CONFIRMED,
                "CONFIRMED": EventStatus.CONFIRMED,
                "Em Planejamento": EventStatus.PLANNING,
                "PLANNING": EventStatus.PLANNING,
                "Em Execução": EventStatus.IN_PROGRESS,
                "IN_PROGRESS": EventStatus.IN_PROGRESS,
                "Entregue": EventStatus.DELIVERED,
                "DELIVERED": EventStatus.DELIVERED,
                "Arquivado": EventStatus.ARCHIVED,
                "ARCHIVED": EventStatus.ARCHIVED,
              };
              return statusMap[backendStatus] || EventStatus.PENDING_APPROVAL;
            };

            const mappedEvents: EventData[] = result.data.map((e: any) => ({
              id: e.id,
              name: e.observacoes_evento || e.tipo_evento_nome || "Evento sem nome", // Fallback mapping
              date: e.data_evento ? e.data_evento.split('T')[0] : "",
              time: e.horario || "00:00",
              type: (e.tipo_evento_nome || "Outro") as EventType, // Map string to enum if possible, or keep string
              status: mapStatus(e.status), // Map from backend status with fallback
              address: {
                street: e.endereco ? e.endereco.split(',')[0] : "",
                number: e.endereco ? e.endereco.split(',')[1]?.split('-')[0]?.trim() || "" : "",
                city: e.endereco ? e.endereco.split('-')[1]?.split('/')[0]?.trim() || "" : "",
                state: e.endereco ? e.endereco.split('/')[1]?.trim() || "" : "",
                zip: "",
                mapLink: e.local_evento?.startsWith('http') ? e.local_evento : undefined
              },
              briefing: e.observacoes_evento || "",
              coverImage: "https://picsum.photos/id/10/800/400", // Placeholder
              contacts: [], // TODO: fetch contacts if needed
              checklist: [],
              ownerId: e.user_id || "unknown",
              photographerIds: Array.isArray(e.assigned_professionals)
                ? e.assigned_professionals.map((a: any) => a.professional_id)
                : [],
              institutionId: "", // TODO
              attendees: e.qtd_formandos,
              fotId: e.fot_id, // UUID

              // Resource Mapping
              qtdFormandos: e.qtd_formandos,
              qtdFotografos: e.qtd_fotografos,
              qtdRecepcionistas: e.qtd_recepcionistas,
              qtdCinegrafistas: e.qtd_cinegrafistas,
              qtdEstudios: e.qtd_estudios,
              qtdPontosFoto: e.qtd_ponto_foto,
              qtdPontosDecorados: e.qtd_ponto_decorado,
              qtdPontosLed: e.qtd_pontos_led,
              qtdPlataforma360: e.qtd_plataforma_360,

              // Joined Fields
              fot: e.fot_numero ?? e.fot_id, // Show Number if available (even 0), else ID
              curso: e.curso_nome,
              instituicao: e.instituicao,
              anoFormatura: e.ano_semestre,
              empresa: e.empresa_nome,
              empresaId: e.empresa_id, // Ensure ID is passed to frontend
              observacoes: e.observacoes_fot,
              typeId: e.tipo_evento_id,
              local_evento: e.local_evento, // Added local_evento mapping
              fot_finalizada: e.fot_finalizada, // Mapped from backend
              fot_pre_venda: e.fot_pre_venda, // Mapped from backend
              pre_venda: e.fot_pre_venda, // Fallback/Alias
              assignments: Array.isArray(e.assigned_professionals)
                ? e.assigned_professionals.map((a: any) => ({
                  professionalId: a.professional_id,
                  status: a.status,
                  reason: a.motivo_rejeicao,
                  funcaoId: a.funcao_id,
                  is_coordinator: a.is_coordinator
                }))
                : [],
              logisticaNotificacaoEnviadaEm: e.logistica_notificacao_enviada_em,
            }));
            setEvents(mappedEvents);
          } else {
            setEvents([]);
          }
        } catch (error) {
          console.error("Failed to fetch events", error);
        } finally {
            setIsLoading(false);
        }
      }
    };
    fetchEvents();
  }, [token, refreshTrigger]); // React to token change and manual refresh

  const refreshEvents = async () => {
    setRefreshTrigger(prev => prev + 1);
  };

  // Fetch pending users from API
  useEffect(() => {
    const fetchUsers = async () => {
      const token = localStorage.getItem('token');
      if (token) {
        try {
          const result = await getPendingUsers(token);
          if (result.data) {
            const mappedUsers: User[] = result.data.map((u: any) => {
              // Map backend roles to frontend enum
              let mappedRole = UserRole.EVENT_OWNER;
              if (u.role === 'profissional') mappedRole = UserRole.PHOTOGRAPHER;
              else if (u.role === 'empresa') mappedRole = UserRole.BUSINESS_OWNER;
              else if (u.role === 'admin') mappedRole = UserRole.SUPERADMIN;
              else if (u.role === 'cliente') mappedRole = UserRole.EVENT_OWNER;

              return {
                id: u.id,
                name: u.name || u.email.split('@')[0],
                email: u.email,
                phone: u.phone || '',
                role: mappedRole,
                approvalStatus: UserApprovalStatus.PENDING,
                createdAt: u.created_at,
                registeredInstitution: mappedRole === UserRole.EVENT_OWNER ? 'N/A' : undefined,
              };
            });
            setPendingUsers(mappedUsers);
          }
        } catch (error) {
          console.error("Failed to fetch pending users", error);
        }
      }
    };
    fetchUsers();

  }, []);

  // Fetch professionals
  useEffect(() => {
    const fetchProfs = async () => {
      const token = localStorage.getItem('token');
      console.log("[DEBUG] Fetching Professionals...", { token });
      if (token) {
        try {
          const result = await getProfessionals(token);
          console.log("[DEBUG] Fetch Professionals Result:", result);
          if (result.data) {
            const mappedProfs: Professional[] = result.data.map((p: any) => ({
              id: p.id,
              usuarioId: p.usuario_id,
              nome: p.nome,
              name: p.nome, // Keep for legacy Dashboard usage
              email: p.email || "",
              funcao_profissional_id: p.funcao_profissional_id,
              role: p.funcao_profissional || p.funcao_nome || "Fotógrafo",
              avatar: p.avatar_url || `https://ui-avatars.com/api/?name=${encodeURIComponent(p.nome)}&background=random`,
              phone: p.whatsapp,

              // Detailed fields
              endereco: p.endereco,
              cidade: p.cidade,
              uf: p.uf,
              cep: p.cep,
              whatsapp: p.whatsapp,
              cpf_cnpj_titular: p.cpf_cnpj_titular,
              banco: p.banco,
              agencia: p.agencia,
              conta_pix: p.conta_pix,
              carro_disponivel: p.carro_disponivel,
              tem_estudio: p.tem_estudio,
              qtd_estudio: p.qtd_estudio,
              tipo_cartao: p.tipo_cartao,
              observacao: p.observacao,

              // Ratings
              qual_tec: p.qual_tec,
              educacao_simpatia: p.educacao_simpatia,
              desempenho_evento: p.desempenho_evento,
              disp_horario: p.disp_horario,
              media: p.media,

              tabela_free: p.tabela_free,
              extra_por_equipamento: p.extra_por_equipamento,
              equipamentos: p.equipamentos,
              
              // Multi-function support
              functions: p.functions || [],

              availability: {}, // Default empty availability
            }));
            setProfessionals(mappedProfs);
          }
        } catch (error) {
          console.error("Failed to fetch professionals", error);
        }
      } else {
        console.warn("[DEBUG] No token found for fetching professionals");
      }
    };
    fetchProfs();
  }, [token]);

  const addEvent = async (event: any) => {
    const token = localStorage.getItem("token");
    if (!token) {
      console.error("No token found");
      throw new Error("Usuário não autenticado");
    }

    try {
      // Check if payload is already mapped (snake_case) or needs mapping (camelCase)
      let payload;
      if (event.fot_id && event.tipo_evento_id) {
        // Already snake_case (from EventForm payload)
        payload = event;
      } else {
        // Legacy camelCase mapping
        payload = {
          fot_id: event.fotId,
          data_evento: event.date + "T" + (event.time || "00:00") + ":00Z",
          tipo_evento_id: event.typeId,
          observacoes_evento: event.name,
          local_evento: event.address?.mapLink || "Local a definir",
          endereco: event.address ? `${event.address.street}, ${event.address.number}, ${event.address.city} - ${event.address.state}` : "",
          horario: event.startTime,
          qtd_formandos: event.attendees ? parseInt(String(event.attendees)) : 0,
          qtd_fotografos: 0,
          qtd_recepcionistas: 0,
          qtd_cinegrafistas: 0,
          qtd_estudios: 0,
          qtd_ponto_foto: 0,
          qtd_ponto_id: 0,
          qtd_ponto_decorado: 0,
          qtd_pontos_led: 0,
          qtd_plataforma_360: 0,
          status_profissionais: "AGUARDANDO",
          foto_faltante: 0,
          recep_faltante: 0,
          cine_faltante: 0,
          logistica_observacoes: "",
          pre_venda: false
        };
      }

      console.log("[DEBUG] addEvent payload:", payload);

      const result = await import("../services/apiService").then(m => m.createAgenda(token, payload));

      if (result.data) {
        console.log("Agenda criada:", result.data);
        // Force reload to ensure complete data consistency
        window.location.href = '/painel';
      } else {
        console.error("Erro ao criar agenda API:", result.error);
        throw new Error(result.error || "Erro ao criar agenda");
      }
    } catch (err: any) {
      console.error("Exception creating agenda:", err);
      throw err; // Re-throw so EventForm knows it failed
    }
  };

  const updateEventStatus = async (id: string, status: EventStatus) => {
    const token = localStorage.getItem('token');
    if (token) {
      try {
        await apiUpdateStatus(token, id, status);
        setEvents((prev) => prev.map((e) => (e.id === id ? { ...e, status } : e)));
      } catch (error) {
        console.error("Failed to update status", error);
      }
    } else {
      // Fallback
      setEvents((prev) => prev.map((e) => (e.id === id ? { ...e, status } : e)));
    }
  };

  const assignPhotographer = async (eventId: string, photographerId: string, funcaoId?: string) => {
    const token = localStorage.getItem('token');
    const event = events.find(e => e.id === eventId);
    if (!event) return;

    const current = event.photographerIds || [];
    const isRemoving = current.includes(photographerId);

    if (token) {
      try {
        if (isRemoving) {
          await apiRemoveProfessional(token, eventId, photographerId);
        } else {
          await apiAssignProfessional(token, eventId, photographerId, funcaoId);
        }
      } catch (error) {
        console.error("Failed to assign/remove professional", error);
        return; // Don't update state if API fails
      }
    }

    setEvents((prev) =>
      prev.map((e) => {
        if (e.id === eventId) {
          const current = e.photographerIds || [];
          const currentAssignments = e.assignments || [];
          if (current.includes(photographerId)) {
            // Remove
            return {
              ...e,
              photographerIds: current.filter(id => id !== photographerId),
              assignments: currentAssignments.filter(a => a.professionalId !== photographerId)
            };
          } else {
            // Add
            // Import AssignmentStatus if needed or use string "PENDENTE" matching the type
            return {
              ...e,
              photographerIds: [...current, photographerId],
              assignments: [...currentAssignments, { professionalId: photographerId, status: "PENDENTE" as any, funcaoId }]
            };
          }
        }
        return e;
      })
    );
  };

  const getEventsByRole = (userId: string, role: string) => {
    if (role === "SUPERADMIN" || role === "BUSINESS_OWNER" || role === "RESEARCHER" || role === "AGENDA_VIEWER" || role === UserRole.AGENDA_VIEWER) {
      return events;
    }
    if (role === "EVENT_OWNER") {
      // Check if logged user has company linked and matches requested user
      if (user && user.id === userId && user.empresaId) {
        return events.filter(e => e.empresaId === user.empresaId);
      }
      return events.filter((e) => e.ownerId === userId);
    }
    if (role === "PHOTOGRAPHER") {
      const professional = professionals.find((p) => p.usuarioId === userId);
      if (!professional) return [];
      const professionalId = professional.id;
      return events.filter((e) => {
        // Incluir apenas eventos onde o fotógrafo está designado
        if (!e.photographerIds.includes(professionalId)) return false;
        
        // Excluir eventos que foram rejeitados pelo fotógrafo
        const assignment = (e.assignments || []).find(a => a.professionalId === professionalId);
        return !assignment || assignment.status !== "REJEITADO";
      });
    }
    return [];
  };

  const addInstitution = (institution: Institution) => {
    setInstitutions((prev) => [...prev, institution]);
  };

  const updateInstitution = (id: string, updatedData: Partial<Institution>) => {
    setInstitutions((prev) =>
      prev.map((inst) => (inst.id === id ? { ...inst, ...updatedData } : inst))
    );
  };

  const getInstitutionsByUserId = (userId: string) => {
    return institutions.filter((inst) => inst.ownerId === userId);
  };

  const getInstitutionById = (id: string) => {
    return institutions.find((inst) => inst.id === id);
  };

  const addCourse = (course: Course) => {
    setCourses((prev) => [...prev, course]);
  };

  const updateCourse = (id: string, updatedData: Partial<Course>) => {
    setCourses((prev) =>
      prev.map((course) =>
        course.id === id ? { ...course, ...updatedData } : course
      )
    );
  };

  const getCoursesByInstitutionId = (institutionId: string) => {
    return courses.filter((course) => course.institutionId === institutionId);
  };

  const getActiveCoursesByInstitutionId = (institutionId: string) => {
    return courses.filter(
      (course) => course.institutionId === institutionId && course.isActive
    );
  };

  const getCourseById = (id: string) => {
    return courses.find((course) => course.id === id);
  };

  // Funções para gerenciar usuários pendentes
  const registerPendingUser = (userData: {
    id: string;
    name: string;
    email: string;
    phone: string;
    registeredInstitution?: string
  }) => {
    const newUser: User = {
      id: userData.id,
      name: userData.name,
      email: userData.email,
      phone: userData.phone,
      role: UserRole.EVENT_OWNER,
      approvalStatus: UserApprovalStatus.PENDING,
      registeredInstitution: userData.registeredInstitution,
      createdAt: new Date().toISOString(),
    };
    setPendingUsers((prev) => [...prev, newUser]);
  };

  const approveUser = async (userId: string) => {
    const token = localStorage.getItem('token');
    if (token) {
      try {
        await apiApproveUser(userId, token);
        setPendingUsers((prev) => prev.filter(user => user.id !== userId));
      } catch (error) {
        console.error("Failed to approve user", error);
      }
    } else {
      // Fallback for mock/testing
      setPendingUsers((prev) =>
        prev.map((user) =>
          user.id === userId
            ? { ...user, approvalStatus: UserApprovalStatus.APPROVED }
            : user
        )
      );
    }
  };

  const rejectUser = (userId: string) => {
    setPendingUsers((prev) =>
      prev.map((user) =>
        user.id === userId
          ? { ...user, approvalStatus: UserApprovalStatus.REJECTED }
          : user
      )
    );
  };

  return (
    <DataContext.Provider
      value={{
        events,
        institutions,
        courses,
        pendingUsers,
        addEvent,
        updateEventStatus,
        assignPhotographer,
        getEventsByRole,
        addInstitution,
        updateInstitution,
        getInstitutionsByUserId,
        getInstitutionById,
        addCourse,
        updateCourse,
        getCoursesByInstitutionId,
        getActiveCoursesByInstitutionId,
        getCourseById,
        registerPendingUser,
        approveUser,
        rejectUser,
        professionals,
        respondToAssignment: async (eventId, status, reason) => {
          const token = localStorage.getItem('token');
          if (!token || !user) return;
          const professional = professionals.find(p => p.usuarioId === user.id);
          if (!professional) return;

          try {
            // Check if `apiUpdateAssignmentStatus` returns { error } object or throws
            // Based on other calls (e.g. line 1089), it likely returns an object.
            const result = await apiUpdateAssignmentStatus(token, eventId, professional.id, status, reason);

            if (result && result.error) {
              alert("Erro ao atualizar status: " + result.error);
              return;
            }

            // Only update state if successful
            setEvents((prev) =>
              prev.map((e) => {
                if (e.id === eventId) {
                  const updatedAssignments = e.assignments?.map(a =>
                    a.professionalId === professional.id ? { ...a, status: status as any, reason } : a
                  ) || [];
                  return { ...e, assignments: updatedAssignments };
                }
                return e;
              })
            );
          } catch (error: any) {
            console.error("Failed to update status", error);
            alert("Erro de conexão ou servidor: " + (error.message || error));
          }
        },
        updateEventDetails: async (id, data) => {
          const token = localStorage.getItem("token");
          if (!token) return;
          const result = await apiUpdateAgenda(token, id, data);
          if (result.error) {
            throw new Error(result.error);
          }

          // Re-fetch logic to ensure state consistency
          // Re-implementing simplified fetch logic here or we can trigger a reload.
          // Since we are in DataContext, we can call a fetch function if we extract it.
          // But to be safe and quick:
          try {
            const result = await import("../services/apiService").then(m => m.getAgendas(token));
            if (result.data) {
              // Re-map events logic from useEffect...
              // This duplication is painful.
              // Alternative: window.location.reload() in Dashboard.
              // But let's assume the user navigates away or we do a simple local merge for Key Fields used in List.
              setEvents(prev => prev.map(evt => {
                if (evt.id === id) {
                  return {
                    ...evt,
                    date: data.data_evento ? data.data_evento.split("T")[0] : evt.date,
                    time: data.horario || evt.time,
                    name: data.observacoes_evento || evt.name,
                    briefing: data.observacoes_evento || evt.briefing,
                    fotId: data.fot_id || evt.fotId,
                    empresaId: data.empresa_id || evt.empresaId, // If provided
                    
                    // Map team resource fields
                    qtdFormandos: data.qtd_formandos ?? evt.qtdFormandos,
                    qtdFotografos: data.qtd_fotografos ?? evt.qtdFotografos,
                    qtdRecepcionistas: data.qtd_recepcionistas ?? evt.qtdRecepcionistas,
                    qtdCinegrafistas: data.qtd_cinegrafistas ?? evt.qtdCinegrafistas,
                    qtdEstudios: data.qtd_estudios ?? evt.qtdEstudios,
                    qtdPontosFoto: data.qtd_pontos_foto ?? evt.qtdPontosFoto,
                    qtdPontosDecorados: data.qtd_pontos_decorados ?? evt.qtdPontosDecorados,
                    qtdPontosLed: data.qtd_pontos_led ?? evt.qtdPontosLed,
                    qtdPlataforma360: data.qtd_plataforma_360 ?? evt.qtdPlataforma360,
                    
                    // Address is hard to parse back to object from payload without logic
                  };
                }
                return evt;
              }));
            }
          } catch (e) { console.error("Refresh failed", e); }
        },
        functions,
        isLoading,
        refreshEvents,
      }}
    >
      {children}
    </DataContext.Provider>
  );
};

export const useData = () => {
  const context = useContext(DataContext);
  if (!context) throw new Error("useData must be used within a DataProvider");
  return context;
};
