import { useState, useEffect } from "react";
import { useAuth } from "../../_assets/utils/AuthProvider";
import API_KEY from "../../_assets/utils/apiKeys";
import { GetDoctorByName } from '../../_assets/utils/Functions-Endpoints/Doctor';

import "../../_assets/css/components/agendamento/FormAgendamento.css";

const ENDPOINT_CRIAR_EXCECAO = "https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctor_exceptions";

const FormCriarExcecao = ({ onCancel, doctorID }) => {
    const { getAuthorizationHeader, user, getUserInfo } = useAuth();

    // mantemos apenas os campos realmente necessários no formulário;
    // profissional (id) e created_by serão preenchidos automaticamente a partir do usuário logado
    const [dadosAtendimento, setDadosAtendimento] = useState({
        profissional: doctorID || '',
        tipoAtendimento: '',
        dataAtendimento: '',
        inicio: '',
        termino: '',
        motivo: ''
    });

    const handleAtendimentoChange = (e) => {
        const { value, name } = e.target;
        setDadosAtendimento(prev => ({
            ...prev,
            [name]: value
        }));
    };

    // preencher automaticamente o id do profissional (doctor_id) vindo do user/prop
    useEffect(() => {
        const resolvedDoctorId = doctorID || user?.doctor_id || user?.id || '';
        setDadosAtendimento(prev => ({
            ...prev,
            profissional: prev.profissional || resolvedDoctorId
        }));
    }, [doctorID, user]);

    const ALLOWED_KINDS = ['disponibilidade_extra', 'bloqueio'];

    // helper: normalize and validate Authorization header -> "Bearer <jwt>"
    const resolveAuthHeader = () => {
        try {
            const maybe = getAuthorizationHeader ? getAuthorizationHeader() : null;
            console.log('[DEBUG] getAuthorizationHeader() ->', maybe);
            let raw = null;

            if (!maybe) {
                // fallback localStorage
                try {
                    const stored = localStorage.getItem('user') || localStorage.getItem('auth') || null;
                    if (stored) {
                        const parsed = JSON.parse(stored);
                        raw = parsed?.access_token || parsed?.token || parsed?.auth?.access_token || null;
                    }
                } catch (e) { console.warn('[DEBUG] parse localStorage failed', e); }
            } else if (typeof maybe === 'string') {
                raw = maybe;
            } else if (typeof maybe === 'object') {
                raw = maybe.Authorization || maybe.authorization || maybe.access_token || maybe.token || null;
            }

            if (!raw) return null;

            // remove any leading "bearer " (case-insensitive) and possible duplicated prefixes
            raw = String(raw).trim().replace(/^(?:bearer\s*)+/i, '');

            console.log('[DEBUG] resolved raw token ->', raw);

            // basic JWT structure check
            if (typeof raw !== 'string' || raw.split('.').length !== 3) {
                console.error('[DEBUG] token not a JWT:', raw);
                return null;
            }

            return `Bearer ${raw}`;
        } catch (err) {
            console.warn('resolveAuthHeader error', err);
            return null;
        }
    };

    const getUidFromAuthHeader = (authHeader) => {
        try {
            if (!authHeader) return null;
            const token = String(authHeader).replace(/Bearer\s+/i, '').trim();
            if (!token || token.split('.').length !== 3) return null;

            // decode base64url payload
            const payloadBase64 = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
            const padded = payloadBase64 + '='.repeat((4 - (payloadBase64.length % 4)) % 4);
            const json = atob(padded);
            const payload = JSON.parse(json);
            return payload.sub || payload.user_id || payload.uid || payload.id || null;
        } catch (err) {
            console.warn('Não foi possível decodificar JWT para obter uid:', err);
            return null;
        }
    };

    const handleSubmitExcecao = async (e) => {
        e.preventDefault();
        console.log('[DEBUG] submit dadosAtendimento ->', dadosAtendimento);

        const authHeader = resolveAuthHeader();
        console.log('[DEBUG] authHeader to send ->', authHeader);
        if (!authHeader) {
            alert('Sessão inválida ou token ausente / inválido. Faça logout e login novamente.');
            return;
        }

        let { profissional, dataAtendimento, tipoAtendimento, inicio, termino, motivo } = dadosAtendimento;

        // tenta resolver profissional automaticamente se ainda não definido
        profissional = profissional || doctorID || user?.doctor_id || user?.id || null;

        // extrai uid do token (se policy do Supabase exigir auth.uid())
        const authUid = getUidFromAuthHeader(authHeader) || user?.id || null;

        // se a policy exige que doctor_id seja igual ao auth.uid(), force o valor aqui
        if (authUid && !profissional) {
            profissional = authUid;
            setDadosAtendimento(prev => ({ ...prev, profissional }));
        }

        // created_by também deve refletir o uid do usuário autenticado (se policy exigir)
        let createdBy = authUid || user?.id || null;

        if (!profissional || !dataAtendimento || !tipoAtendimento || !motivo) {
            alert("Por favor, verifique: médico, data, tipo e motivo são obrigatórios.");
            return;
        }

        const mappedKind = tipoAtendimento;
        if (!ALLOWED_KINDS.includes(mappedKind)) {
            alert(`Tipo inválido: "${tipoAtendimento}". Tipos aceitos: ${ALLOWED_KINDS.join(', ')}`);
            return;
        }

        const startTime = inicio ? inicio + ":00" : null;
        const endTime = termino ? termino + ":00" : null;

        const payload = {
            doctor_id: profissional,
            date: dataAtendimento,
            kind: mappedKind,
            start_time: startTime,
            end_time: endTime,
            reason: motivo,
            created_by: createdBy
        };

        // monta headers do POST usando authHeader já normalizado
        const myHeaders = new Headers();
        myHeaders.append('Content-Type', 'application/json');
        myHeaders.append('Authorization', authHeader);
        if (API_KEY) myHeaders.append('apikey', API_KEY);

        // envia
        try {
            const response = await fetch(ENDPOINT_CRIAR_EXCECAO, {
                method: 'POST',
                headers: myHeaders,
                body: JSON.stringify(payload),
                redirect: 'follow'
            });

            const text = await response.text();
            let result;
            try { result = JSON.parse(text); } catch { result = { message: text }; }

            if (response.ok || response.status === 201) {
                alert(`Exceção criada com sucesso.`);
                onCancel(true);
            } else {
                console.error("Erro ao criar exceção:", result);
                alert(`Erro ao criar exceção. Status: ${response.status}. ${result.message || ''}`);
            }
        } catch (error) {
            console.error("Erro na requisição para criar exceção:", error);
            alert("Erro de comunicação com o servidor.");
        }
    };

    // exibimos informações do médico logado de forma somente leitura (preenchidas automaticamente)
    const [displayDoctorName, setDisplayDoctorName] = useState(user?.full_name || user?.name || '');
    const displayDoctorId = doctorID || user?.doctor_id || user?.id || '';

    // preenche dados do médico usando a função de informações do usuário (UserInfos / getUserInfo)
    useEffect(() => {
        let cancelled = false;
        const resolvedDoctorId = doctorID || user?.doctor_id || user?.id || null;
        const userName = user?.full_name || user?.name || user?.username || '';

        const tryFillFromUserInfo = async () => {
            try {
                // primeiro, tenta usar getUserInfo() se disponível
                let info = null;
                if (typeof getUserInfo === 'function') {
                    try {
                        // se getUserInfo precisa de header, passe-o; caso contrário, a função interna deve usar auth
                        const authHeader = resolveAuthHeader();
                        // se getUserInfo aceita header, você pode adaptar; aqui tentamos chamar sem args
                        info = await getUserInfo();
                    } catch (e) {
                        // fallback: sem info
                    }
                }

                // se não veio info, use user
                const profile = info || user || {};

                const profileId = profile.doctor_id || profile.id || resolvedDoctorId;
                const profileName = profile.full_name || profile.name || userName;

                if (!cancelled && profileName) setDisplayDoctorName(profileName);
                if (!cancelled && profileId) {
                    setDadosAtendimento(prev => ({ ...prev, profissional: prev.profissional || profileId }));
                    return;
                }

                // fallback: tentar buscar por nome via endpoint de médicos (usa auth header normalizado)
                if (userName) {
                    const authHeader = resolveAuthHeader();
                    if (!authHeader) {
                        console.warn('No auth header available for GetDoctorByName lookup');
                    } else {
                        const doctor = await GetDoctorByName(userName, authHeader);
                        if (!cancelled && doctor) {
                            setDisplayDoctorName(doctor.full_name || doctor.name || userName);
                            setDadosAtendimento(prev => ({ ...prev, profissional: doctor.id || doctor.doctor_id || prev.profissional }));
                            return;
                        }
                    }
                }

                // último fallback
                if (!cancelled) {
                    setDisplayDoctorName(userName || '');
                    if (resolvedDoctorId) setDadosAtendimento(prev => ({ ...prev, profissional: prev.profissional || resolvedDoctorId }));
                }
            } catch (err) {
                if (cancelled) return;
                console.warn('Erro ao preencher dados do médico via UserInfos/getUserInfo:', err);
                setDisplayDoctorName(userName || '');
                if (resolvedDoctorId) setDadosAtendimento(prev => ({ ...prev, profissional: prev.profissional || resolvedDoctorId }));
            }
        };

        tryFillFromUserInfo();
        return () => { cancelled = true; };
    }, [doctorID, user, getUserInfo, getAuthorizationHeader]);

    return (
        <div className="form-container">
            <form className="form-agendamento" onSubmit={handleSubmitExcecao}>
                <h2 className="section-title">Informações da Nova Exceção</h2>

                {/* Médico agora não é editável/visível — dados preenchidos automaticamente */}
                <div className="campo-informacoes-atendimento">
                    <div className="campo-de-input">
                        <label>Tipo de exceção *</label>
                        <select name="tipoAtendimento" onChange={handleAtendimentoChange} value={dadosAtendimento.tipoAtendimento} required>
                            <option value="" disabled>Selecione o tipo de exceção</option>
                            <option value="disponibilidade_extra">Disponibilidade Extra</option>
                            <option value="bloqueio">Bloqueio</option>
                        </select>
                    </div>
                </div>

                <section id="informacoes-atendimento-segunda-linha">
                    <section id="informacoes-atendimento-segunda-linha-esquerda">
                        <div className="campo-informacoes-atendimento">
                            <div className="campo-de-input">
                                <label>Data *</label>
                                <input
                                    type="date"
                                    name="dataAtendimento"
                                    required
                                    value={dadosAtendimento.dataAtendimento}
                                    onChange={handleAtendimentoChange}
                                />
                            </div>
                        </div>

                        <div className="campo-informacoes-atendimento">
                            <div className="campo-de-input">
                                <label>Início (Opcional)</label>
                                <input
                                    type="time"
                                    name="inicio"
                                    value={dadosAtendimento.inicio}
                                    onChange={handleAtendimentoChange}
                                />
                            </div>

                            <div className="campo-de-input">
                                <label>Término (Opcional)</label>
                                <input
                                    type="time"
                                    name="termino"
                                    value={dadosAtendimento.termino}
                                    onChange={handleAtendimentoChange}
                                />
                            </div>
                        </div>
                    </section>

                    <section className="informacoes-atendimento-segunda-linha-direita">
                        <div className="campo-de-input">
                            <label>Motivo da exceção *</label>
                            <textarea
                                name="motivo"
                                rows="4"
                                cols="1"
                                required
                                value={dadosAtendimento.motivo}
                                onChange={handleAtendimentoChange}
                            ></textarea>
                        </div>
                    </section>
                </section>

                <div className="form-actions">
                    <button type="submit" className="btn-primary">Criar Exceção</button>
                    <button type="button" className="btn-cancel" onClick={() => onCancel(false)}>Cancelar</button>
                </div>
            </form>
        </div>
    );
};

export default FormCriarExcecao;