<script>
  import { createVisit, updateVisit, fetchVisit, 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, MapPin, User, FileText, Activity } from 'lucide-svelte';

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

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

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

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

  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' },
  ];

  $effect(() => {
    if (open) {
      loadLocations();
      loadContacts();
      if (visit) {
        // Edit mode - populate form
        formData = {
          InternalPVID: visit.InternalPVID || null,
          PVID: visit.PVID || '',
          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 || '',
        };
      } else {
        // Create mode - reset form
        formData = {
          InternalPVID: null,
          PVID: '',
          PatientID: patient?.PatientID || '',
          PVCreateDate: new Date().toISOString().slice(0, 16),
          ADTCode: '',
          LocationID: '',
          LocCode: '',
          AttDoc: '',
          AdmDoc: '',
          RefDoc: '',
          CnsDoc: '',
          DiagCode: '',
          Diagnosis: '',
          EndDate: '',
          ArchivedDate: '',
        };
      }
    }
  });

  async function loadLocations() {
    try {
      const response = await fetchLocations();
      locations = Array.isArray(response.data) ? response.data : [];
    } catch (err) {
      console.error('Failed to load locations:', err);
    }
  }

  async function loadContacts() {
    try {
      const response = await fetchContacts();
      contacts = Array.isArray(response.data) ? response.data : [];
    } catch (err) {
      console.error('Failed to load contacts:', err);
    }
  }

  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',
    }))
  );

  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;

    saving = 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);
        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', // Default to update if no code
          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);
        // Don't fail the whole operation if ADT creation fails
      }

      open = false;
      onSave?.();
    } catch (err) {
      toastError(err.message || 'Failed to save visit');
    } finally {
      saving = false;
    }
  }
</script>

<Modal bind:open title={isEdit ? 'Edit Visit' : 'New Visit'} size="lg">
  {#if loading}
    <div class="flex items-center justify-center py-12">
      <span class="loading loading-spinner loading-lg text-primary"></span>
    </div>
  {:else}
    <form class="space-y-6" onsubmit={(e) => e.preventDefault()}>
      <!-- Patient Info Display -->
      {#if patient}
        <div class="p-4 bg-base-200 rounded-lg">
          <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>
      {/if}

      <!-- 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-4">
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
            {#if isEdit}
              <div class="form-control">
                <label class="label" for="pvid">
                  <span class="label-text font-medium">Visit ID</span>
                </label>
                <input
                  id="pvid"
                  type="text"
                  class="input input-bordered w-full"
                  bind:value={formData.PVID}
                  placeholder="Enter visit ID"
                />
              </div>
            {/if}

            <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-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-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-4">
          <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-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-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-bordered w-full"
                  bind:value={formData.ArchivedDate}
                />
              </div>
            </div>
          </div>
        </div>
      {/if}
    </form>
  {/if}

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