import React, { useState, useMemo, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import API_KEY from '../components/utils/apiKeys.js';
import AgendamentoCadastroManager from '../pages/AgendamentoCadastroManager.jsx';
import { useAuth } from '../components/utils/AuthProvider.js';
import dayjs from 'dayjs';
import 'dayjs/locale/pt-br';
import isBetween from 'dayjs/plugin/isBetween';
import localeData from 'dayjs/plugin/localeData';
import { ChevronLeft, ChevronRight, Edit, Trash2 } from 'lucide-react';
import "../pages/style/Agendamento.css";
import '../pages/style/FilaEspera.css';
import '../pages/style/TableDoctor.css';
import Spinner from '../components/Spinner.jsx';

dayjs.locale('pt-br');
dayjs.extend(isBetween);
dayjs.extend(localeData);

const Agendamento = ({ setDictInfo }) => {
  const navigate = useNavigate();
  const { getAuthorizationHeader, user } = useAuth();

  const [isLoading, setIsLoading] = useState(true);
  const [DictAgendamentosOrganizados, setDictAgendamentosOrganizados] = useState({});
  const [filaEsperaData, setFilaDeEsperaData] = useState([]);
  const [FiladeEspera, setFiladeEspera] = useState(false);
  const [PageNovaConsulta, setPageConsulta] = useState(false);

  const [currentDate, setCurrentDate] = useState(dayjs());
  const [selectedDay, setSelectedDay] = useState(dayjs());
  const [quickJump, setQuickJump] = useState({
    month: currentDate.month(),
    year: currentDate.year()
  });

  const [isCancelModalOpen, setIsCancelModalOpen] = useState(false);
  const [appointmentToCancel, setAppointmentToCancel] = useState(null);
  const [cancellationReason, setCancellationReason] = useState('');

  // Estados para filtro, ordenação e paginação da fila de espera
  const [waitlistSearch, setWaitlistSearch] = useState('');
  const [waitSortKey, setWaitSortKey] = useState(null);
  const [waitSortDir, setWaitSortDir] = useState('asc');
  const [waitPage, setWaitPage] = useState(1);
  const [waitPerPage, setWaitPerPage] = useState(10);

  const authHeader = useMemo(() => getAuthorizationHeader(), [getAuthorizationHeader]);

  useEffect(() => {
    const carregarDados = async () => {
      const patientId = user?.patient_id || "6e7f8829-0574-42df-9290-8dbb70f75ada";

      if (!authHeader) {
        console.warn("Header de autorização não disponível.");
        setIsLoading(false);
        return;
      }

      setIsLoading(true);
      try {
        const myHeaders = new Headers({ "Authorization": authHeader, "apikey": API_KEY });
        const requestOptions = { method: 'GET', headers: myHeaders };
        const response = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?select=*,doctors(full_name)&patient_id=eq.${patientId}`, requestOptions);

        if (!response.ok) throw new Error(`Erro na requisição: ${response.statusText}`);

        const consultasBrutas = await response.json() || [];

        const newDict = {};
        const newFila = [];

        for (const agendamento of consultasBrutas) {
          const agendamentoMelhorado = {
            ...agendamento,
            medico_nome: agendamento.doctors?.full_name || 'Médico não informado'
          };

          if (agendamento.status === "requested") {
            newFila.push({ agendamento: agendamentoMelhorado, Infos: agendamentoMelhorado });
          } else {
            const diaAgendamento = dayjs(agendamento.scheduled_at).format("YYYY-MM-DD");
            if (newDict[diaAgendamento]) {
              newDict[diaAgendamento].push(agendamentoMelhorado);
            } else {
              newDict[diaAgendamento] = [agendamentoMelhorado];
            }
          }
        }

        for (const key in newDict) {
          newDict[key].sort((a, b) => a.scheduled_at.localeCompare(b.scheduled_at));
        }

        setDictAgendamentosOrganizados(newDict);
        setFilaDeEsperaData(newFila);

      } catch (err) {
        console.error('Falha ao buscar ou processar agendamentos:', err);
        setDictAgendamentosOrganizados({});
        setFilaDeEsperaData([]);
      } finally {
        setIsLoading(false);
      }
    };

    carregarDados();
  }, [authHeader, user]);

  const updateAppointmentStatus = async (id, updates) => {
    const myHeaders = new Headers({
      "Authorization": authHeader, "apikey": API_KEY, "Content-Type": "application/json"
    });
    const requestOptions = { method: 'PATCH', headers: myHeaders, body: JSON.stringify(updates) };

    try {
      const response = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?id=eq.${id}`, requestOptions);
      if (!response.ok) throw new Error('Falha ao atualizar o status.');
      return true;
    } catch (error) {
      console.error('Erro de rede/servidor:', error);
      return false;
    }
  };

  const handleCancelClick = (appointmentId) => {
    setAppointmentToCancel(appointmentId);
    setCancellationReason('');
    setIsCancelModalOpen(true);
  };

  const executeCancellation = async () => {
    if (!appointmentToCancel) return;
    setIsLoading(true);
    const motivo = cancellationReason.trim() || "Cancelado pelo paciente (motivo não especificado)";
    const success = await updateAppointmentStatus(appointmentToCancel, {
      status: "cancelled",
      cancellation_reason: motivo,
      updated_at: new Date().toISOString()
    });

    setIsCancelModalOpen(false);
    setAppointmentToCancel(null);
    setCancellationReason('');

    if (success) {
      alert("Solicitação cancelada com sucesso!");

      setDictAgendamentosOrganizados(prev => {
        const newDict = { ...prev };
        for (const date in newDict) {
          newDict[date] = newDict[date].filter(app => app.id !== appointmentToCancel);
        }
        return newDict;
      });
      setFilaDeEsperaData(prev => prev.filter(item => item.agendamento.id !== appointmentToCancel));
    } else {
      alert("Falha ao cancelar a solicitação.");
    }
    setIsLoading(false);
  };

  const handleQuickJumpChange = (type, value) => setQuickJump(prev => ({ ...prev, [type]: Number(value) }));
  const applyQuickJump = () => {
    const newDate = dayjs().year(quickJump.year).month(quickJump.month).date(1);
    setCurrentDate(newDate);
    setSelectedDay(newDate);
  };
  const dateGrid = useMemo(() => {
    const grid = [];
    const startOfMonth = currentDate.startOf('month');
    let currentDay = startOfMonth.subtract(startOfMonth.day(), 'day');
    for (let i = 0; i < 42; i++) {
      grid.push(currentDay);
      currentDay = currentDay.add(1, 'day');
    }
    return grid;
  }, [currentDate]);
  const weekDays = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'];
  const handleDateClick = (day) => setSelectedDay(day);

  // Filtro e ordenação da fila de espera
  const filaEsperaFiltrada = useMemo(() => {
    if (!waitlistSearch.trim()) return filaEsperaData;
    const term = waitlistSearch.toLowerCase();
    return filaEsperaData.filter(
      (item) =>
        (item?.Infos?.medico_nome?.toLowerCase() || '').includes(term)
    );
  }, [waitlistSearch, filaEsperaData]);

  const applySortingWaitlist = (arr) => {
    if (!Array.isArray(arr) || !waitSortKey) return arr;
    const copy = [...arr];
    if (waitSortKey === 'medico') {
      copy.sort((a, b) => (a?.Infos?.medico_nome || '').localeCompare(b?.Infos?.medico_nome || ''));
    } else if (waitSortKey === 'data') {
      copy.sort((a, b) =>
        new Date(a?.agendamento?.created_at || 0) - new Date(b?.agendamento?.created_at || 0)
      );
    }
    if (waitSortDir === 'desc') copy.reverse();
    return copy;
  };

  const filaEsperaOrdenada = applySortingWaitlist(filaEsperaFiltrada);
  const waitTotalPages = Math.ceil(filaEsperaOrdenada.length / waitPerPage) || 1;
  const waitIndiceInicial = (waitPage - 1) * waitPerPage;
  const waitIndiceFinal = waitIndiceInicial + waitPerPage;
  const filaEsperaPaginada = filaEsperaOrdenada.slice(waitIndiceInicial, waitIndiceFinal);

  const gerarNumerosWaitPages = () => {
    const paginas = [];
    const paginasParaMostrar = 5;
    let inicio = Math.max(1, waitPage - Math.floor(paginasParaMostrar / 2));
    let fim = Math.min(waitTotalPages, inicio + paginasParaMostrar - 1);
    inicio = Math.max(1, fim - paginasParaMostrar + 1);
    for (let i = inicio; i <= fim; i++) paginas.push(i);
    return paginas;
  };

  useEffect(() => {
    setWaitPage(1);
  }, [waitlistSearch, waitSortKey, waitSortDir]);


  if (isLoading) {
    return (
      <div className="form-container" style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '50vh' }}>
        <Spinner />
      </div>
    );
  }

  return (
    <div>
      <h1>Minhas consultas</h1>
      <div className="btns-gerenciamento-e-consulta" style={{ display: 'flex', gap: '10px', marginBottom: '20px' }}>
        <button
          className="btn-adicionar-consulta"
          onClick={() => {
            setPageConsulta(true);
            setFiladeEspera(false);
          }}
          style={{
            backgroundColor: PageNovaConsulta ? '#1d4ed8' : undefined
          }}
        >
          <i className="bi bi-plus-circle"></i> Solicitar Agendamento
        </button>
        <button
          className="btn-adicionar-consulta"
          onClick={() => {
            setFiladeEspera(!FiladeEspera);
            setPageConsulta(false);
          }}
          style={{
            backgroundColor: FiladeEspera && !PageNovaConsulta ? '#1d4ed8' : undefined
          }}
        >
          <i className="bi bi-list-task me-1"></i> Fila de Espera ({filaEsperaData.length})
        </button>
      </div>

      {!PageNovaConsulta ? (
        <div className='atendimento-eprocura'>
          <section className='calendario-ou-filaespera'>
            {!FiladeEspera ? (
              <div className="calendar-wrapper">
                <div className="calendar-info-panel">
                  <div className="info-date-display"><span>{selectedDay.format('MMM')}</span><strong>{selectedDay.format('DD')}</strong></div>
                  <div className="info-details"><h3>{selectedDay.format('dddd')}</h3><p>{selectedDay.format('D [de] MMMM [de] YYYY')}</p></div>
                  <div className="appointments-list">
                    <h4>Consultas para {selectedDay.format('DD/MM')}</h4>
                    {(DictAgendamentosOrganizados[selectedDay.format('YYYY-MM-DD')]?.length > 0) ? (
                      DictAgendamentosOrganizados[selectedDay.format('YYYY-MM-DD')].map(app => (
                        <div key={app.id} className="appointment-item" data-status={app.status}>
                          <div className="item-time">{dayjs(app.scheduled_at).format('HH:mm')}</div>
                          <div className="item-details">
                            <span>Consulta com Dr(a). {app.medico_nome}</span>
                          </div>
                          <div className='item-actions'>
                            {app.status !== 'cancelled' && dayjs(app.scheduled_at).isAfter(dayjs()) && (
                              <button className="btn btn-sm btn-outline-danger" onClick={() => handleCancelClick(app.id)} title="Cancelar Consulta">
                                <Trash2 size={16} />
                              </button>
                            )}
                          </div>
                        </div>
                      ))
                    ) : (<div className="no-appointments-info"><p>Nenhuma consulta agendada para esta data.</p></div>)}
                  </div>
                </div>
                <div className="calendar-main">
                  <div className="calendar-legend">
                    <div className="legend-item" data-status="completed">Realizado</div>
                    <div className="legend-item" data-status="confirmed">Confirmado</div>
                    <div className="legend-item" data-status="agendado">Agendado</div>
                    <div className="legend-item" data-status="cancelled">Cancelado</div>
                  </div>
                  <div className="calendar-controls">
                    <div className="date-indicator">
                      <h2>{currentDate.format('MMMM [de] YYYY')}</h2>
                      <div className="quick-jump-controls" style={{ display: 'flex', gap: '5px', marginTop: '10px' }}>
                        <select value={quickJump.month} onChange={(e) => handleQuickJumpChange('month', e.target.value)} className="form-select form-select-sm w-auto">
                          {dayjs.months().map((month, index) => (<option key={index} value={index}>{month.charAt(0).toUpperCase() + month.slice(1)}</option>))}
                        </select>
                        <select value={quickJump.year} onChange={(e) => handleQuickJumpChange('year', e.target.value)} className="form-select form-select-sm w-auto">
                          {Array.from({ length: 11 }, (_, i) => dayjs().year() - 5 + i).map(year => (<option key={year} value={year}>{year}</option>))}
                        </select>
                        <button className="btn btn-sm btn-outline-primary" onClick={applyQuickJump} disabled={quickJump.month === currentDate.month() && quickJump.year === currentDate.year()}>Ir</button>
                      </div>
                    </div>
                    <div className="nav-buttons">
                      <button onClick={() => setCurrentDate(c => c.subtract(1, 'month'))}><ChevronLeft size={20} /></button>
                      <button onClick={() => setCurrentDate(dayjs())}>Hoje</button>
                      <button onClick={() => setCurrentDate(c => c.add(1, 'month'))}><ChevronRight size={20} /></button>
                    </div>
                  </div>
                  <div className="calendar-grid">
                    {weekDays.map(day => <div key={day} className="day-header">{day}</div>)}
                    {dateGrid.map((day, index) => {
                      const appointmentsOnDay = DictAgendamentosOrganizados[day.format('YYYY-MM-DD')] || [];
                      const cellClasses = `day-cell ${day.isSame(currentDate, 'month') ? 'current-month' : 'other-month'} ${day.isSame(dayjs(), 'day') ? 'today' : ''} ${day.isSame(selectedDay, 'day') ? 'selected' : ''}`;
                      return (
                        <div key={index} className={cellClasses} onClick={() => handleDateClick(day)}>
                          <span>{day.format('D')}</span>
                          {appointmentsOnDay.length > 0 && <div className="appointments-indicator">{appointmentsOnDay.length}</div>}
                        </div>
                      );
                    })}
                  </div>
                </div>
              </div>
            ) : (
              <div className="page-content table-doctor-container">
                <div className="table-doctor-card">
                  <div className="card-header">
                    <h4 className="card-title mb-0">Minhas Solicitações em Fila de Espera</h4>
                  </div>
                  <div className="card-body">
                    {/* ===== FILTROS PADRONIZADOS ===== */}
                    <div className="table-doctor-filters">
                      <h5 className="mb-3">
                        <i className="bi bi-funnel-fill me-2 text-primary"></i> Filtros
                      </h5>

                      {/* Busca */}
                      <div className="mb-3">
                        <input
                          type="text"
                          className="form-control"
                          placeholder="Buscar por médico..."
                          value={waitlistSearch}
                          onChange={(e) => setWaitlistSearch(e.target.value)}
                        />
                      </div>

                      {/* Linha de Filtros Básicos */}
                      <div className="d-flex flex-wrap align-items-center gap-3 mb-3">
                        {/* Ordenação */}
                        <div className="d-flex align-items-center gap-2">
                          <label className="form-label mb-0 text-muted small">Ordenar por:</label>
                          <select
                            className="form-select form-select-sm compact-select sort-select"
                            style={{ minWidth: "180px" }}
                            value={waitSortKey ? `${waitSortKey}-${waitSortDir}` : ''}
                            onChange={(e) => {
                              const v = e.target.value;
                              if (!v) {
                                setWaitSortKey(null);
                                setWaitSortDir('asc');
                                return;
                              }
                              const [k, d] = v.split('-');
                              setWaitSortKey(k);
                              setWaitSortDir(d);
                            }}
                          >
                            <option value="">Sem ordenação</option>
                            <option value="medico-asc">Médico (A-Z)</option>
                            <option value="medico-desc">Médico (Z-A)</option>
                            <option value="data-asc">Data (mais antiga)</option>
                            <option value="data-desc">Data (mais recente)</option>
                          </select>
                        </div>
                      </div>

                      {/* Contador */}
                      <div className="mt-3">
                        <div className="contador-medicos">
                          {filaEsperaFiltrada.length} DE {filaEsperaData.length} SOLICITAÇÕES ENCONTRADAS
                        </div>
                      </div>
                    </div>

                    {/* ===== TABELA SIMPLIFICADA ===== */}
                    <div className="table-responsive mt-4">
                      <table className="table table-striped table-hover table-doctor-table">
                        <thead>
                          <tr>
                            <th>Médico Solicitado</th>
                            <th>Data da Solicitação</th>
                            <th>Ações</th>
                          </tr>
                        </thead>
                        <tbody>
                          {filaEsperaPaginada.length > 0 ? (
                            filaEsperaPaginada.map((item) => (
                              <tr key={item.agendamento.id}>
                                <td>Dr(a). {item.Infos?.medico_nome}</td>
                                <td>{dayjs(item.agendamento.created_at).format('DD/MM/YYYY HH:mm')}</td>
                                <td>
                                  <button 
                                    className="btn btn-sm btn-delete" 
                                    onClick={() => handleCancelClick(item.agendamento.id)}
                                  >
                                    <i className="bi bi-trash me-1"></i> Cancelar
                                  </button>
                                </td>
                              </tr>
                            ))
                          ) : (
                            <tr>
                              <td colSpan="3" className="text-center py-4">
                                <div className="text-muted">
                                  <i className="bi bi-search display-4"></i>
                                  <p className="mt-2">Nenhuma solicitação na fila de espera.</p>
                                </div>
                              </td>
                            </tr>
                          )}
                        </tbody>
                      </table>

                      {/* ===== PAGINAÇÃO ===== */}
                      {filaEsperaFiltrada.length > 0 && (
                        <div className="d-flex justify-content-between align-items-center mt-3">
                          <div className="d-flex align-items-center">
                            <span className="me-2 text-muted">Itens por página:</span>
                            <select
                              className="form-select form-select-sm w-auto"
                              value={waitPerPage}
                              onChange={(e) => {
                                setWaitPerPage(Number(e.target.value));
                                setWaitPage(1);
                              }}
                            >
                              <option value={5}>5</option>
                              <option value={10}>10</option>
                              <option value={25}>25</option>
                              <option value={50}>50</option>
                            </select>
                          </div>

                          <div className="d-flex align-items-center">
                            <span className="me-3 text-muted">
                              Página {waitPage} de {waitTotalPages} •
                              Mostrando {waitIndiceInicial + 1}-{Math.min(waitIndiceFinal, filaEsperaFiltrada.length)} de {filaEsperaFiltrada.length} solicitações
                            </span>

                            <nav>
                              <ul className="pagination pagination-sm mb-0">
                                <li className={`page-item ${waitPage === 1 ? 'disabled' : ''}`}>
                                  <button
                                    className="page-link"
                                    onClick={() => setWaitPage(p => Math.max(1, p - 1))}
                                  >
                                    <i className="bi bi-chevron-left"></i>
                                  </button>
                                </li>

                                {gerarNumerosWaitPages().map(pagina => (
                                  <li
                                    key={pagina}
                                    className={`page-item ${pagina === waitPage ? 'active' : ''}`}
                                  >
                                    <button
                                      className="page-link"
                                      onClick={() => setWaitPage(pagina)}
                                    >
                                      {pagina}
                                    </button>
                                  </li>
                                ))}

                                <li className={`page-item ${waitPage === waitTotalPages ? 'disabled' : ''}`}>
                                  <button
                                    className="page-link"
                                    onClick={() => setWaitPage(p => Math.min(waitTotalPages, p + 1))}
                                  >
                                    <i className="bi bi-chevron-right"></i>
                                  </button>
                                </li>
                              </ul>
                            </nav>
                          </div>
                        </div>
                      )}
                    </div>
                  </div>
                </div>
              </div>
            )}
          </section>
        </div>
      ) : (
        <AgendamentoCadastroManager setPageConsulta={setPageConsulta} />
      )}

      {/* ===== MODAL DE CANCELAMENTO ===== */}
      {isCancelModalOpen && (
        <div
          className="modal fade show delete-modal"
          style={{ display: "block", backgroundColor: "rgba(0, 0, 0, 0.5)" }}
          tabIndex="-1"
          onClick={(e) => e.target.classList.contains("modal") && setIsCancelModalOpen(false)}
        >
          <div className="modal-dialog modal-dialog-centered">
            <div className="modal-content">
              <div className="modal-header" style={{ backgroundColor: '#dc3545', color: 'white' }}>
                <h5 className="modal-title">Confirmação de Cancelamento</h5>
              </div>

              <div className="modal-body">
                <p className="mb-3 fs-5">Deseja realmente cancelar esta consulta?</p>
                <p className="text-muted small mb-2">Esta ação não pode ser desfeita.</p>
                
                <label className="form-label fw-bold mt-3">Motivo do cancelamento (opcional):</label>
                <textarea
                  className="form-control"
                  value={cancellationReason}
                  onChange={(e) => setCancellationReason(e.target.value)}
                  placeholder="Ex: Precisei viajar, motivo pessoal, etc."
                  rows="4"
                  style={{ resize: 'none' }}
                ></textarea>
              </div>

              <div className="modal-footer">
                <button
                  type="button"
                  className="btn btn-primary"
                  onClick={() => setIsCancelModalOpen(false)}
                >
                  Voltar
                </button>

                <button
                  type="button"
                  className="btn btn-danger"
                  onClick={executeCancellation}
                >
                  <i className="bi bi-trash me-1"></i> Cancelar Consulta
                </button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

export default Agendamento;
