<script>
  import { onMount } from 'svelte';
  import { fetchVisitsByPatient, createVisit, updateVisit, createADT } from '$lib/api/visits.js';
  import { fetchLocations } from '$lib/api/locations.js';
  import { fetchContacts } from '$lib/api/contacts.js';
  import { success as toastSuccess, error as toastError } from '$lib/utils/toast.js';
  import Modal from '$lib/components/Modal.svelte';
  import SelectDropdown from '$lib/components/SelectDropdown.svelte';
  import { Calendar, Clock, MapPin, FileText, Plus, Edit2, ArrowLeft, User, Activity } from 'lucide-svelte';

  /** @type {{ open: boolean, patient: any | null }} */
  let { open = $bindable(false), patient = null } = $props();

  let visits = $state([]);
  let loading = $state(false);
  let mode = $state('list'); // 'list' or 'form'
  let selectedVisit = $state(null);

  // Form state
  let formSaving = $state(false);
  let locations = $state([]);
  let contacts = $state([]);
  let formErrors = $state({});
  let activeTab = $state('info'); // 'info', 'diagnosis'

  let formData = $state({
    InternalPVID: null,
    PatientID: '',
    PVCreateDate: '',
    ADTCode: '',
    LocationID: '',
    LocCode: '',
    AttDoc: '',
    AdmDoc: '',
    RefDoc: '',
    CnsDoc: '',
    DiagCode: '',
    Diagnosis: '',
    EndDate: '',
    ArchivedDate: '',
  });

  const adtTypeOptions = [
    { value: 'A04', label: 'Register (Outpatient/ER)' },
    { value: 'A01', label: 'Admit (Inpatient)' },
    { value: 'A02', label: 'Transfer' },
    { value: 'A03', label: 'Discharge' },
    { value: 'A08', label: 'Update Information' },
    { value: 'A11', label: 'Cancel Admit' },
    { value: 'A13', label: 'Cancel Discharge' },
  ];

  const isEdit = $derived(!!selectedVisit?.InternalPVID);

  const locationOptions = $derived(
    locations.map((l) => ({
      value: l.LocationID || l.LocCode || '',
      label: l.LocFull || l.LocCode || 'Unknown',
    }))
  );

  const doctorOptions = $derived(
    contacts.map((c) => ({
      value: c.ContactID || c.ContactCode || '',
      label: [c.NamePrefix, c.NameFirst, c.NameMiddle, c.NameLast].filter(Boolean).join(' ') || c.ContactCode || 'Unknown',
    }))
  );

  onMount(() => {
    if (patient && open) {
      loadVisits();
    }
  });

  $effect(() => {
    if (open && patient) {
      loadVisits();
    }
  });

  async function loadVisits() {
    if (!patient?.InternalPID) return;
    
    loading = true;
    try {
      const response = await fetchVisitsByPatient(patient.InternalPID);
      console.log('Visit API response:', response);
      
      // Handle different response structures
      if (Array.isArray(response)) {
        visits = response;
      } else if (response.data && Array.isArray(response.data)) {
        visits = response.data;
      } else if (response.visits && Array.isArray(response.visits)) {
        visits = response.visits;
      } else {
        visits = [];
      }
      
      console.log('Processed visits:', visits);
    } catch (err) {
      toastError(err.message || 'Failed to load visits');
      visits = [];
    } finally {
      loading = false;
    }
  }

  function formatDate(dateStr) {
    if (!dateStr) return '-';
    return new Date(dateStr).toLocaleDateString();
  }

  function formatDateTime(dateStr) {
    if (!dateStr) return '-';
    return new Date(dateStr).toLocaleString();
  }

  async function openCreateModal() {
    selectedVisit = null;
    await loadFormData();
    resetForm();
    mode = 'form';
  }

  async function openEditModal(visit) {
    selectedVisit = visit;
    await loadFormData();
    populateForm(visit);
    mode = 'form';
  }

  function backToList() {
    mode = 'list';
    selectedVisit = null;
    activeTab = 'info';
  }

  async function loadFormData() {
    try {
      const [locResponse, contactResponse] = await Promise.all([
        fetchLocations(),
        fetchContacts(),
      ]);
      locations = Array.isArray(locResponse.data) ? locResponse.data : [];
      contacts = Array.isArray(contactResponse.data) ? contactResponse.data : [];
    } catch (err) {
      console.error('Failed to load form data:', err);
    }
  }

  function resetForm() {
    formData = {
      InternalPVID: null,
      PatientID: patient?.PatientID || '',
      PVCreateDate: new Date().toISOString().slice(0, 16),
      ADTCode: '',
      LocationID: '',
      LocCode: '',
      AttDoc: '',
      AdmDoc: '',
      RefDoc: '',
      CnsDoc: '',
      DiagCode: '',
      Diagnosis: '',
      EndDate: '',
      ArchivedDate: '',
    };
    formErrors = {};
  }

  function populateForm(visit) {
    formData = {
      InternalPVID: visit.InternalPVID || null,
      PatientID: visit.PatientID || patient?.PatientID || '',
      PVCreateDate: visit.PVCreateDate || visit.PVACreateDate || '',
      ADTCode: visit.ADTCode || '',
      LocationID: visit.LocationID || '',
      LocCode: visit.LocCode || '',
      AttDoc: visit.AttDoc || '',
      AdmDoc: visit.AdmDoc || '',
      RefDoc: visit.RefDoc || '',
      CnsDoc: visit.CnsDoc || '',
      DiagCode: visit.DiagCode || '',
      Diagnosis: visit.Diagnosis || '',
      EndDate: visit.EndDate || '',
      ArchivedDate: visit.ArchivedDate || '',
    };
    formErrors = {};
  }

  function validateForm() {
    const errors = {};
    if (!formData.PatientID?.trim()) {
      errors.PatientID = 'Patient ID is required';
    }
    if (!formData.PVCreateDate) {
      errors.PVCreateDate = 'Visit date is required';
    }
    if (!formData.ADTCode?.trim()) {
      errors.ADTCode = 'Visit type is required';
    }
    formErrors = errors;
    return Object.keys(errors).length === 0;
  }

  async function handleSubmit() {
    if (!validateForm()) return;

    formSaving = true;
    try {
      const payload = { ...formData };

      // Remove empty fields
      Object.keys(payload).forEach((key) => {
        if (payload[key] === '' || payload[key] === null) {
          delete payload[key];
        }
      });

      let savedVisit;
      if (isEdit) {
        savedVisit = await updateVisit(payload.InternalPVID, payload);
        toastSuccess('Visit updated successfully');
      } else {
        savedVisit = await createVisit(payload);
        toastSuccess('Visit created successfully');
      }

      // Create ADT record for the visit action
      try {
        const adtPayload = {
          InternalPVID: savedVisit?.InternalPVID || payload.InternalPVID,
          ADTCode: payload.ADTCode || 'A08',
          LocationID: payload.LocationID,
          LocCode: payload.LocCode,
          AttDoc: payload.AttDoc,
          AdmDoc: payload.AdmDoc,
          RefDoc: payload.RefDoc,
          CnsDoc: payload.CnsDoc,
        };
        await createADT(adtPayload);
      } catch (adtErr) {
        console.warn('Failed to create ADT record:', adtErr);
      }

      backToList();
      await loadVisits();
    } catch (err) {
      toastError(err.message || 'Failed to save visit');
    } finally {
      formSaving = false;
    }
  }
</script>

<Modal bind:open title={mode === 'list' ? 'Patient Visits' : isEdit ? 'Edit Visit' : 'New Visit'} size="xl">
  {#if patient}
    {#if mode === 'list'}
      <!-- Visit List View -->
      <div class="mb-4 p-4 bg-base-200 rounded-lg">
        <div class="flex items-center justify-between">
          <div>
            <h3 class="font-bold text-lg">
              {[patient.Prefix, patient.NameFirst, patient.NameMiddle, patient.NameLast].filter(Boolean).join(' ')}
            </h3>
            <p class="text-sm text-gray-600">Patient ID: {patient.PatientID}</p>
          </div>
          <button class="btn btn-primary btn-sm" onclick={openCreateModal}>
            <Plus class="w-4 h-4 mr-1" />
            New Visit
          </button>
        </div>
      </div>

      {#if loading}
        <div class="flex items-center justify-center py-12">
          <span class="loading loading-spinner loading-lg text-primary"></span>
        </div>
      {:else if visits.length === 0}
        <div class="text-center py-12 text-gray-500">
          <Calendar class="w-16 h-16 mx-auto mb-4 opacity-50" />
          <p class="text-lg">No visits found</p>
          <p class="text-sm">This patient has no visit records.</p>
        </div>
      {:else}
        <div class="space-y-3">
          {#each visits as visit}
            <div class="card bg-base-100 shadow border border-base-200 hover:shadow-md transition-shadow">
              <div class="card-body p-4">
                <div class="flex items-start justify-between">
                  <div class="flex-1">
                    <div class="flex items-center gap-2 mb-2">
                      <Calendar class="w-4 h-4 text-primary" />
                      <span class="font-semibold">{formatDate(visit.PVACreateDate || visit.PVCreateDate)}</span>
                      {#if !visit.EndDate && !visit.ArchivedDate}
                        <span class="badge badge-sm badge-success">Active</span>
                      {:else}
                        <span class="badge badge-sm badge-ghost">Closed</span>
                      {/if}
                    </div>
                    
                    <div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
                      {#if visit.ADTCode}
                        <div>
                          <span class="text-gray-500">Type:</span>
                          <span class="ml-1">{visit.ADTCode}</span>
                        </div>
                      {/if}
                      
                      {#if visit.LocCode || visit.LocationID}
                        <div class="flex items-center gap-1">
                          <MapPin class="w-3 h-3 text-gray-400" />
                          <span class="text-gray-500">Location:</span>
                          <span class="ml-1">{visit.LocCode || visit.LocationID || '-'}</span>
                        </div>
                      {/if}
                      
                      {#if visit.AttDoc || visit.AdmDoc || visit.RefDoc || visit.CnsDoc}
                        <div>
                          <span class="text-gray-500">Doctor:</span>
                          <span class="ml-1">{visit.AttDoc || visit.AdmDoc || visit.RefDoc || visit.CnsDoc || '-'}</span>
                        </div>
                      {/if}
                      
                      {#if visit.PVACreateDate || visit.PVCreateDate}
                        <div class="flex items-center gap-1">
                          <Clock class="w-3 h-3 text-gray-400" />
                          <span class="text-gray-500">Time:</span>
                          <span class="ml-1">{formatDateTime(visit.PVACreateDate || visit.PVCreateDate)}</span>
                        </div>
                      {/if}
                    </div>

                    {#if visit.DiagCode || visit.Diagnosis}
                      <div class="mt-3 pt-3 border-t border-base-200">
                        <div class="flex items-start gap-2">
                          <FileText class="w-4 h-4 text-gray-400 mt-0.5" />
                          <div>
                            <span class="text-gray-500 text-sm">Diagnosis:</span>
                            <p class="text-sm mt-1">{visit.DiagCode || visit.Diagnosis || '-'}</p>
                          </div>
                        </div>
                      </div>
                    {/if}
                    
                    <div class="mt-2 text-xs text-gray-400">
                      Visit ID: {visit.PVID || visit.InternalPVID || '-'}
                    </div>
                  </div>
                  <div class="flex gap-1 ml-4">
                    <button
                      class="btn btn-sm btn-ghost"
                      title="Edit"
                      onclick={() => openEditModal(visit)}
                    >
                      <Edit2 class="w-4 h-4" />
                    </button>
                  </div>
                </div>
              </div>
            </div>
          {/each}
        </div>
      {/if}
    {:else}
      <!-- Visit Form View -->
      <div class="mb-4">
        <button class="btn btn-ghost btn-sm" onclick={backToList}>
          <ArrowLeft class="w-4 h-4 mr-1" />
          Back to Visits
        </button>
      </div>

      <!-- Patient Info Display -->
      <div class="p-4 bg-base-200 rounded-lg mb-4">
        <div class="flex items-center gap-2">
          <User class="w-4 h-4 text-gray-500" />
          <span class="font-medium">
            {[patient.Prefix, patient.NameFirst, patient.NameMiddle, patient.NameLast].filter(Boolean).join(' ')}
          </span>
          <span class="text-gray-500">({patient.PatientID})</span>
        </div>
      </div>

      <form class="space-y-3" onsubmit={(e) => e.preventDefault()}>
        <!-- Tabs -->
        <div class="tabs tabs-bordered">
          <button
            type="button"
            class="tab tab-lg {activeTab === 'info' ? 'tab-active' : ''}"
            onclick={() => activeTab = 'info'}
          >
            <Calendar class="w-4 h-4 mr-2" />
            Visit Info
          </button>
          <button
            type="button"
            class="tab tab-lg {activeTab === 'diagnosis' ? 'tab-active' : ''}"
            onclick={() => activeTab = 'diagnosis'}
          >
            <Activity class="w-4 h-4 mr-2" />
            Diagnosis & Status
          </button>
        </div>

        <!-- Tab: Visit Info -->
        {#if activeTab === 'info'}
          <div class="space-y-3">
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div class="form-control">
                <label class="label" for="patientId">
                  <span class="label-text font-medium">Patient ID</span>
                  <span class="label-text-alt text-error">*</span>
                </label>
                <input
                  id="patientId"
                  type="text"
                  class="input input-sm input-bordered w-full"
                  class:input-error={formErrors.PatientID}
                  bind:value={formData.PatientID}
                  placeholder="Enter patient ID"
                  disabled={!!patient}
                />
                {#if formErrors.PatientID}
                  <span class="text-error text-sm mt-1">{formErrors.PatientID}</span>
                {/if}
              </div>

              <div class="form-control">
                <label class="label" for="visitDate">
                  <span class="label-text font-medium">Visit Date</span>
                  <span class="label-text-alt text-error">*</span>
                </label>
                <input
                  id="visitDate"
                  type="datetime-local"
                  class="input input-sm input-bordered w-full"
                  class:input-error={formErrors.PVCreateDate}
                  bind:value={formData.PVCreateDate}
                />
                {#if formErrors.PVCreateDate}
                  <span class="text-error text-sm mt-1">{formErrors.PVCreateDate}</span>
                {/if}
              </div>
            </div>

            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
              <SelectDropdown
                label="Visit Type"
                name="adtCode"
                bind:value={formData.ADTCode}
                options={adtTypeOptions}
                placeholder="Select visit type..."
                required={true}
                error={formErrors.ADTCode}
              />

              <SelectDropdown
                label="Location"
                name="location"
                bind:value={formData.LocationID}
                options={locationOptions}
                placeholder="Select location..."
              />
            </div>

            <div class="border-t border-base-200 pt-4 mt-4">
              <h4 class="font-medium text-gray-700 mb-4">Doctors</h4>
              <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <SelectDropdown
                  label="Attending Doctor"
                  name="attDoc"
                  bind:value={formData.AttDoc}
                  options={doctorOptions}
                  placeholder="Select attending doctor..."
                />

                <SelectDropdown
                  label="Admitting Doctor"
                  name="admDoc"
                  bind:value={formData.AdmDoc}
                  options={doctorOptions}
                  placeholder="Select admitting doctor..."
                />
              </div>

              <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
                <SelectDropdown
                  label="Referring Doctor"
                  name="refDoc"
                  bind:value={formData.RefDoc}
                  options={doctorOptions}
                  placeholder="Select referring doctor..."
                />

                <SelectDropdown
                  label="Consulting Doctor"
                  name="cnsDoc"
                  bind:value={formData.CnsDoc}
                  options={doctorOptions}
                  placeholder="Select consulting doctor..."
                />
              </div>
            </div>
          </div>
        {/if}

        <!-- Tab: Diagnosis & Status -->
        {#if activeTab === 'diagnosis'}
          <div class="space-y-3">
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div class="form-control">
                <label class="label" for="diagCode">
                  <span class="label-text font-medium">Diagnosis Code</span>
                </label>
                <input
                  id="diagCode"
                  type="text"
                  class="input input-sm input-bordered w-full"
                  bind:value={formData.DiagCode}
                  placeholder="Enter diagnosis code"
                />
              </div>
            </div>

            <div class="form-control">
              <label class="label" for="diagnosis">
                <span class="label-text font-medium">Diagnosis Description</span>
              </label>
              <textarea
                id="diagnosis"
                class="textarea textarea-bordered w-full"
                bind:value={formData.Diagnosis}
                placeholder="Enter diagnosis description"
                rows="3"
              ></textarea>
            </div>

            <div class="border-t border-base-200 pt-4 mt-4">
              <h4 class="font-medium text-gray-700 mb-4">Visit Status</h4>
              <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div class="form-control">
                  <label class="label" for="endDate">
                    <span class="label-text font-medium">End Date</span>
                  </label>
                  <input
                    id="endDate"
                    type="datetime-local"
                    class="input input-sm input-bordered w-full"
                    bind:value={formData.EndDate}
                  />
                </div>

                <div class="form-control">
                  <label class="label" for="archivedDate">
                    <span class="label-text font-medium">Archived Date</span>
                  </label>
                  <input
                    id="archivedDate"
                    type="datetime-local"
                    class="input input-sm input-bordered w-full"
                    bind:value={formData.ArchivedDate}
                  />
                </div>
              </div>
            </div>
          </div>
        {/if}
      </form>
    {/if}
  {/if}

  {#snippet footer()}
    {#if mode === 'list'}
      <button class="btn btn-ghost" onclick={() => (open = false)} type="button">Close</button>
    {:else}
      <div class="flex justify-end gap-2">
        <button class="btn btn-ghost" onclick={backToList} type="button">
          Cancel
        </button>
        <button class="btn btn-primary" onclick={handleSubmit} disabled={formSaving} type="button">
          {#if formSaving}
            <span class="loading loading-spinner loading-sm mr-2"></span>
          {/if}
          {formSaving ? 'Saving...' : 'Save'}
        </button>
      </div>
    {/if}
  {/snippet}
</Modal>
