<!--
|--------------------------------------------------------------------------
| Agência PSI — CadastroRapidoMedico.vue
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Dialog de cadastro rápido de médicos / profissionais de referência.
| Usado em PatientsCadastroPage (campo "Encaminhado por") e acessível
| pela futura MedicosCadastroPage.
|
| Props:
|   visible (Boolean)
|
| Emits:
|   update:visible
|   created   — objeto do médico recém-criado
|   selected  — médico selecionado da lista (para preencher campo no form)
|
| Tabela: public.medicos  (ver medicos.sql)
|--------------------------------------------------------------------------
-->
<script setup>
import { ref, computed, watch } from 'vue'
import { useToast }      from 'primevue/usetoast'
import { digitsOnly, fmtPhone } from '@/utils/validators'
import { useMedicos } from '@/features/medicos/composables/useMedicos'

// ─────────────────────────────────────────────────────────
const props = defineProps({
  visible: { type: Boolean, default: false },
  editId:  { type: String,  default: null  },  // uuid do médico a editar (null = novo)
})
const emit = defineEmits(['update:visible', 'created', 'selected'])

const toast = useToast()
const medicosStore = useMedicos()

// ─────────────────────────────────────────────────────────
// Views: 'list' | 'create' | 'edit'
// ─────────────────────────────────────────────────────────
const view       = ref('list')
const medicos    = medicosStore.rows  // alias reativo da lista carregada pelo composable
const loading    = ref(false)         // local — só pra UI da list view (composable usa loading próprio internamente)
const searchTerm = ref('')
const editingId  = ref(null)   // uuid do médico sendo editado

// Form
const saving              = ref(false)
const formErr             = ref('')
const showTelProfissional = ref(false)
const showTelPessoal      = ref(false)

function resetForm () {
  return {
    nome:                '',
    crm:                 '',
    especialidade:       '',
    especialidade_outra: '',
    telefone_profissional: '',
    telefone_pessoal:      '',
    email:               '',
    clinica:             '',
    cidade:              '',
    estado:              'SP',
    observacoes:         '',
  }
}
const form = ref(resetForm())

// ─────────────────────────────────────────────────────────
// Especialidades
// ─────────────────────────────────────────────────────────
const especialidadesOpts = [
  { label: 'Psiquiatria',               value: 'Psiquiatria'               },
  { label: 'Neurologia',                value: 'Neurologia'                },
  { label: 'Neuropsiquiatria infantil', value: 'Neuropsiquiatria infantil' },
  { label: 'Clínica geral',             value: 'Clínica geral'             },
  { label: 'Pediatria',                 value: 'Pediatria'                 },
  { label: 'Geriatria',                 value: 'Geriatria'                 },
  { label: 'Endocrinologia',            value: 'Endocrinologia'            },
  { label: 'Psicologia (encaminhador)', value: 'Psicologia (encaminhador)' },
  { label: 'Assistência social',        value: 'Assistência social'        },
  { label: 'Fonoaudiologia',            value: 'Fonoaudiologia'            },
  { label: 'Terapia ocupacional',       value: 'Terapia ocupacional'       },
  { label: 'Fisioterapia',              value: 'Fisioterapia'              },
  { label: 'Outra',                     value: '__outra__'                 },
]

const especialidadeFinal = computed(() =>
  form.value.especialidade === '__outra__'
    ? (form.value.especialidade_outra.trim() || null)
    : (form.value.especialidade || null)
)

// ─────────────────────────────────────────────────────────
// Computed
// ─────────────────────────────────────────────────────────
const filteredMedicos = computed(() => {
  const q = searchTerm.value.toLowerCase().trim()
  if (!q) return medicos.value
  return medicos.value.filter(m =>
    (m.nome || '').toLowerCase().includes(q) ||
    (m.especialidade || '').toLowerCase().includes(q) ||
    (m.crm || '').toLowerCase().includes(q) ||
    (m.clinica || '').toLowerCase().includes(q)
  )
})

// ─────────────────────────────────────────────────────────
// Load
// ─────────────────────────────────────────────────────────
async function loadMedicos () {
  loading.value = true
  await medicosStore.loadForOwner()
  if (medicosStore.error.value) {
    toast.add({ severity: 'error', summary: 'Erro', detail: medicosStore.error.value, life: 3500 })
  }
  loading.value = false
}

watch(() => props.visible, async (v) => {
  if (v) {
    searchTerm.value  = ''
    formErr.value     = ''
    showTelProfissional.value = false
    showTelPessoal.value      = false
    if (props.editId) {
      // Abre direto no form de edição com os dados carregados
      await loadMedicoForEdit(props.editId)
    } else {
      view.value = 'list'
      loadMedicos()
    }
  }
})

async function loadMedicoForEdit (id) {
  const data = await medicosStore.fetchById(id)
  if (!data) {
    toast.add({ severity: 'error', summary: 'Erro', detail: medicosStore.error.value || 'Médico não encontrado.', life: 3000 })
    view.value = 'list'
    loadMedicos()
    return
  }
  form.value = {
    nome:                data.nome || '',
    crm:                 data.crm || '',
    especialidade:       data.especialidade || '',
    especialidade_outra: '',
    telefone_profissional: data.telefone_profissional ? fmtPhone(data.telefone_profissional) : '',
    telefone_pessoal:      data.telefone_pessoal      ? fmtPhone(data.telefone_pessoal)      : '',
    email:               data.email || '',
    clinica:             data.clinica || '',
    cidade:              data.cidade || '',
    estado:              data.estado || 'SP',
    observacoes:         data.observacoes || '',
  }
  editingId.value = id
  view.value = 'edit'
}

// ─────────────────────────────────────────────────────────
// Ações lista
// ─────────────────────────────────────────────────────────
function openCreate () {
  form.value = resetForm()
  formErr.value = ''
  editingId.value = null
  showTelProfissional.value = false
  showTelPessoal.value = false
  view.value = 'create'
}
function backToList () {
  view.value      = 'list'
  formErr.value   = ''
  editingId.value = null
  loadMedicos()
}
function selectMedico (m) {
  emit('selected', m)
  close()
}

// ─────────────────────────────────────────────────────────
// Salvar
// ─────────────────────────────────────────────────────────
async function saveMedico () {
  const nome = String(form.value.nome || '').trim()
  if (!nome) { formErr.value = 'Informe o nome do médico.'; return }
  if (form.value.especialidade === '__outra__' && !form.value.especialidade_outra.trim()) {
    formErr.value = 'Informe a especialidade.'; return
  }

  saving.value = true; formErr.value = ''
  const isUpdate = !!editingId.value

  try {
    // Payload: owner_id e tenant_id são injetados pelo repository.
    // Repository sanitiza trim/nullif em strings; componente só normaliza telefones (digits-only).
    const payload = {
      nome,
      crm:                   form.value.crm || null,
      especialidade:         especialidadeFinal.value,
      telefone_profissional: form.value.telefone_profissional ? digitsOnly(form.value.telefone_profissional) : null,
      telefone_pessoal:      form.value.telefone_pessoal      ? digitsOnly(form.value.telefone_pessoal)      : null,
      email:                 form.value.email || null,
      clinica:               form.value.clinica || null,
      cidade:                form.value.cidade || null,
      estado:                form.value.estado || null,
      observacoes:           form.value.observacoes || null,
    }

    const data = isUpdate
      ? await medicosStore.update(editingId.value, payload)
      : await medicosStore.create(payload)

    toast.add({
      severity: 'success',
      summary: isUpdate ? 'Médico atualizado' : 'Médico cadastrado',
      detail: `Dr(a). ${data.nome} ${isUpdate ? 'atualizado' : 'adicionado'}.`,
      life: 2500
    })

    emit(isUpdate ? 'selected' : 'created', data)
    emit('selected', data)
    close()
  } catch (e) {
    const msg = e?.message || ''
    if (e?.code === '23505' || /duplicate/i.test(msg)) {
      formErr.value = 'Já existe um cadastro com este CRM para este profissional.'
    } else {
      formErr.value = msg || 'Falha ao salvar.'
    }
  } finally { saving.value = false }
}

function close () {
  emit('update:visible', false)
}
</script>

<template>
  <Dialog
    :visible="visible"
    @update:visible="$emit('update:visible', $event)"
    modal
    :draggable="false"
    :closable="!saving"
    :dismissableMask="!saving"
    maximizable
    class="dc-dialog w-[50rem]"
    :breakpoints="{ '1199px': '90vw', '768px': '94vw' }"
    :pt="{
      header:           { class: '!p-3 !rounded-t-[12px] border-b border-[var(--surface-border)] bg-[var(--surface-ground)]' },
      content:          { class: '!p-3' },
      footer:           { class: '!p-0 !rounded-b-[12px] border-t border-[var(--surface-border)] bg-[var(--surface-ground)]' },
      pcCloseButton:    { root: { class: '!rounded-md hover:!text-red-500' } },
      pcMaximizeButton: { root: { class: '!rounded-md hover:!text-primary' } },
    }"
    pt:mask:class="backdrop-blur-xs"
  >
    <!-- ── Header ──────────────────────────────────────── -->
    <template #header>
      <div class="flex w-full items-center justify-between gap-3 px-1">
        <div class="flex items-center gap-3 min-w-0">
          <span class="flex items-center justify-center w-7 h-7 rounded-lg bg-teal-100 text-teal-600 text-[0.8rem] shrink-0">
            <i class="pi pi-user-plus"/>
          </span>
          <div class="min-w-0">
            <div class="text-base font-semibold truncate">Médicos &amp; referências</div>
            <div class="text-xs opacity-50">
              <template v-if="view === 'list'">Selecione ou cadastre um novo profissional</template>
              <template v-else-if="editingId">Editar dados do médico</template>
              <template v-else>Novo médico / profissional de referência</template>
            </div>
          </div>
        </div>
      </div>
    </template>

    <!-- ══════════════════════════════════════════════════
         VIEW: LISTA
    ════════════════════════════════════════════════════ -->
    <div v-if="view === 'list'" class="flex flex-col -mt-1">

      <!-- Busca -->
      <div class="mb-3">
        <IconField>
          <InputIcon class="pi pi-search"/>
          <InputText v-model="searchTerm" class="w-full" variant="filled" placeholder="Buscar por nome, especialidade, CRM…"/>
        </IconField>
      </div>

      <!-- Lista -->
      <div class="flex flex-col gap-1 max-h-[300px] overflow-y-auto pr-0.5">

        <div v-if="loading" class="flex items-center justify-center py-8 gap-2 text-[var(--text-color-secondary)]">
          <i class="pi pi-spin pi-spinner"/> Carregando…
        </div>

        <div v-else-if="!filteredMedicos.length" class="flex flex-col items-center py-8 gap-2 text-center">
          <div class="w-12 h-12 rounded-full bg-teal-50 flex items-center justify-center">
            <i class="pi pi-user-plus text-xl text-teal-300"/>
          </div>
          <div class="text-[0.82rem] text-[var(--text-color-secondary)]">
            {{ searchTerm ? 'Nenhum médico encontrado.' : 'Nenhum médico cadastrado ainda.' }}
          </div>
        </div>

        <button
          v-for="m in filteredMedicos" :key="m.id"
          type="button"
          class="flex items-center gap-3 rounded-lg px-3 py-2.5 text-left border border-transparent hover:bg-[var(--surface-ground)] hover:border-teal-100 transition-all duration-100 w-full group"
          @click="selectMedico(m)"
        >
          <!-- Iniciais -->
          <div class="w-9 h-9 rounded-full bg-teal-100 flex items-center justify-center font-black text-[0.75rem] text-teal-700 shrink-0 group-hover:bg-teal-200 transition-colors select-none">
            {{ (m.nome||'?').split(' ').filter(Boolean).map(w=>w[0].toUpperCase()).slice(0,2).join('') }}
          </div>

          <div class="flex-1 min-w-0">
            <div class="text-[0.88rem] font-semibold text-[var(--text-color)] truncate leading-tight">
              Dr(a). {{ m.nome }}
            </div>
            <div class="text-[0.7rem] text-[var(--text-color-secondary)] truncate mt-0.5">
              <template v-if="m.especialidade">{{ m.especialidade }}</template>
              <template v-if="m.crm"> · CRM {{ m.crm }}</template>
              <template v-if="m.clinica"> · {{ m.clinica }}</template>
              <template v-if="m.cidade"> · {{ m.cidade }}<template v-if="m.estado">/{{ m.estado }}</template></template>
            </div>
          </div>

          <i class="pi pi-chevron-right text-[0.68rem] text-[var(--text-color-secondary)] opacity-30 group-hover:opacity-70 shrink-0"/>
        </button>
      </div>

      <div class="border-t border-[var(--surface-border)] mt-3 pt-3">
        <Button
          label="Cadastrar novo médico"
          icon="pi pi-plus"
          severity="secondary"
          outlined
          class="rounded-full w-full"
          @click="openCreate"
        />
      </div>
    </div>

    <!-- ══════════════════════════════════════════════════
         VIEW: CRIAR
    ════════════════════════════════════════════════════ -->
    <div v-else class="flex flex-col gap-3.5 -mt-1">

      <!-- Voltar -->
      <button
        type="button"
        class="flex items-center gap-1.5 text-[0.77rem] text-[var(--text-color-secondary)] hover:text-teal-600 transition-colors w-fit"
        @click="backToList"
      >
        <i class="pi pi-arrow-left text-[0.72rem]"/> Voltar para a lista
      </button>

      <!-- Nome + CRM -->
      <div class="grid grid-cols-1 gap-3.5 sm:grid-cols-[1fr_150px]">
        <div>
          <FloatLabel variant="on">
            <IconField>
              <InputIcon class="pi pi-user"/>
              <InputText id="m_nome" v-model="form.nome" class="w-full" variant="filled" autofocus/>
            </IconField>
            <label for="m_nome">Nome completo *</label>
          </FloatLabel>
        </div>
        <div>
          <FloatLabel variant="on">
            <InputText id="m_crm" v-model="form.crm" class="w-full" variant="filled"/>
            <label for="m_crm">CRM (ex: 123456/SP)</label>
          </FloatLabel>
        </div>
      </div>

      <!-- Especialidade -->
      <div>
        <FloatLabel variant="on">
          <Select
            id="m_esp"
            v-model="form.especialidade"
            :options="especialidadesOpts"
            optionLabel="label"
            optionValue="value"
            class="w-full"
            variant="filled"
            filter
            filterPlaceholder="Buscar especialidade…"
          />
          <label for="m_esp">Especialidade</label>
        </FloatLabel>
      </div>

      <!-- Especialidade "Outra" — aparece condicionalmente -->
      <Transition
        enter-active-class="transition-all duration-150 ease-out"
        enter-from-class="opacity-0 -translate-y-1"
        leave-active-class="transition-all duration-100 ease-in"
        leave-to-class="opacity-0 -translate-y-1"
      >
        <div v-if="form.especialidade === '__outra__'">
          <FloatLabel variant="on">
            <InputText
              id="m_esp_outra"
              v-model="form.especialidade_outra"
              class="w-full"
              variant="filled"
              placeholder="Descreva a especialidade"
            />
            <label for="m_esp_outra">Qual especialidade? *</label>
          </FloatLabel>
        </div>
      </Transition>

      <!-- Divider contatos -->
      <div class="flex items-center gap-2">
        <span class="text-[0.63rem] font-bold uppercase tracking-widest text-teal-500">Contatos</span>
        <div class="flex-1 h-px bg-teal-200/50"/>
      </div>

      <!-- Telefone profissional — máscara normal, olho aparece só quando preenchido -->
      <div>
        <div class="relative">
          <InputMask
            id="m_tel_prof"
            v-model="form.telefone_profissional"
            mask="(99) 99999-9999"
            :unmask="false"
            class="w-full"
            :class="form.telefone_profissional ? 'pr-10' : ''"
            variant="filled"
            placeholder="(00) 00000-0000"
            autocomplete="off"
          />
          <!-- Olho — só renderiza quando há dígitos preenchidos -->
          <button
            v-if="form.telefone_profissional?.replace(/\D/g,'').length >= 10"
            type="button"
            class="absolute right-3 top-1/2 -translate-y-1/2 transition-colors z-10"
            :class="showTelProfissional ? 'text-teal-600' : 'text-[var(--text-color-secondary)] hover:text-teal-600'"
            tabindex="-1"
            :title="showTelProfissional ? 'Ocultar número' : 'Revelar número completo'"
            @click="showTelProfissional = !showTelProfissional"
          >
            <i :class="showTelProfissional ? 'pi pi-eye-slash' : 'pi pi-eye'" class="text-[0.9rem]"/>
          </button>
        </div>
        <!-- Número revelado abaixo do campo -->
        <div
          v-if="showTelProfissional && form.telefone_profissional"
          class="mt-1.5 flex items-center gap-1.5 px-2.5 py-1.5 rounded-md bg-teal-50 border border-teal-200/60"
        >
          <i class="pi pi-phone text-teal-500 text-[0.75rem] shrink-0"/>
          <span class="text-[0.82rem] font-semibold text-teal-700 tracking-wide">{{ form.telefone_profissional }}</span>
        </div>
        <div v-else class="mt-1 text-[0.63rem] text-[var(--text-color-secondary)] opacity-60">
          Número do consultório ou clínica.
        </div>
      </div>

      <!-- Telefone pessoal — mesma lógica -->
      <div>
        <div class="relative">
          <InputMask
            id="m_tel_pes"
            v-model="form.telefone_pessoal"
            mask="(99) 99999-9999"
            :unmask="false"
            class="w-full"
            :class="form.telefone_pessoal ? 'pr-10' : ''"
            variant="filled"
            placeholder="(00) 00000-0000"
            autocomplete="off"
          />
          <button
            v-if="form.telefone_pessoal?.replace(/\D/g,'').length >= 10"
            type="button"
            class="absolute right-3 top-1/2 -translate-y-1/2 transition-colors z-10"
            :class="showTelPessoal ? 'text-teal-600' : 'text-[var(--text-color-secondary)] hover:text-teal-600'"
            tabindex="-1"
            :title="showTelPessoal ? 'Ocultar número' : 'Revelar número completo'"
            @click="showTelPessoal = !showTelPessoal"
          >
            <i :class="showTelPessoal ? 'pi pi-eye-slash' : 'pi pi-eye'" class="text-[0.9rem]"/>
          </button>
        </div>
        <div
          v-if="showTelPessoal && form.telefone_pessoal"
          class="mt-1.5 flex items-center gap-1.5 px-2.5 py-1.5 rounded-md bg-teal-50 border border-teal-200/60"
        >
          <i class="pi pi-mobile text-teal-500 text-[0.75rem] shrink-0"/>
          <span class="text-[0.82rem] font-semibold text-teal-700 tracking-wide">{{ form.telefone_pessoal }}</span>
        </div>
        <div v-else class="mt-1 text-[0.63rem] text-[var(--text-color-secondary)] opacity-60">
          Pessoal / WhatsApp — toque no olho para revelar após digitar.
        </div>
      </div>

      <!-- Email -->
      <div>
        <FloatLabel variant="on">
          <IconField>
            <InputIcon class="pi pi-envelope"/>
            <InputText id="m_email" v-model="form.email" class="w-full" variant="filled"/>
          </IconField>
          <label for="m_email">E-mail profissional</label>
        </FloatLabel>
      </div>

      <!-- Divider localização -->
      <div class="flex items-center gap-2">
        <span class="text-[0.63rem] font-bold uppercase tracking-widest text-teal-500">Localização</span>
        <div class="flex-1 h-px bg-teal-200/50"/>
      </div>

      <!-- Clínica + Cidade + UF -->
      <div>
        <FloatLabel variant="on">
          <IconField>
            <InputIcon class="pi pi-building"/>
            <InputText id="m_clinica" v-model="form.clinica" class="w-full" variant="filled"/>
          </IconField>
          <label for="m_clinica">Clínica / Hospital</label>
        </FloatLabel>
      </div>

      <div class="grid grid-cols-[1fr_90px] gap-3">
        <div>
          <FloatLabel variant="on">
            <IconField>
              <InputIcon class="pi pi-map-marker"/>
              <InputText id="m_cidade" v-model="form.cidade" class="w-full" variant="filled"/>
            </IconField>
            <label for="m_cidade">Cidade</label>
          </FloatLabel>
        </div>
        <div>
          <FloatLabel variant="on">
            <InputText id="m_uf" v-model="form.estado" class="w-full" variant="filled"/>
            <label for="m_uf">UF</label>
          </FloatLabel>
        </div>
      </div>

      <!-- Observações -->
      <div>
        <FloatLabel variant="on">
          <Textarea id="m_obs" v-model="form.observacoes" rows="2" class="w-full" variant="filled"/>
          <label for="m_obs">Observações internas</label>
        </FloatLabel>
        <div class="mt-1 text-[0.63rem] text-[var(--text-color-secondary)] opacity-60">
          Ex: aceita WhatsApp, convênios atendidos, melhor horário.
        </div>
      </div>

      <!-- Erro -->
      <div v-if="formErr" class="flex items-start gap-1.5 text-[0.82rem] text-red-500 font-medium">
        <i class="pi pi-exclamation-circle mt-0.5 shrink-0"/> {{ formErr }}
      </div>
    </div>

    <!-- ── Footer ──────────────────────────────────────── -->
    <template #footer>
      <div class="flex items-center justify-end gap-2 px-3 py-3">
        <Button
          v-if="view !== 'list'"
          label="Cancelar"
          severity="secondary"
          text
          class="rounded-full hover:!text-red-500"
          :disabled="saving"
          @click="backToList"
        />
        <Button
          v-else
          label="Fechar"
          severity="secondary"
          text
          class="rounded-full hover:!text-red-500"
          @click="close"
        />
        <Button
          v-if="view !== 'list'"
          :label="editingId ? 'Salvar alterações' : 'Salvar médico'"
          icon="pi pi-check"
          class="rounded-full"
          :loading="saving"
          @click="saveMedico"
        />
      </div>
    </template>
  </Dialog>
</template>