<script>
  import { onMount } from 'svelte';
  import { fetchProvinces, fetchCities } from '$lib/api/geography.js';
  import { createPatient, updatePatient } from '$lib/api/patients.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 { User, MapPin, Contact } from 'lucide-svelte';

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

  let loading = $state(false);
  let saving = $state(false);
  let provinces = $state([]);
  let cities = $state([]);
  let formErrors = $state({});
  let activeTab = $state('personal'); // 'personal' or 'location'

  let formData = $state({
    InternalPID: null,
    PatientID: '',
    Prefix: '',
    NameFirst: '',
    NameMiddle: '',
    NameLast: '',
    NameMaiden: '',
    Suffix: '',
    Sex: '',
    Birthdate: '',
    PlaceOfBirth: '',
    Citizenship: '',
    Street_1: '',
    Street_2: '',
    Street_3: '',
    Province: '',
    City: '',
    ZIP: '',
    Country: '',
    Phone: '',
    MobilePhone: '',
    EmailAddress1: '',
    EmailAddress2: '',
    Race: '',
    MaritalStatus: '',
    Religion: '',
    Ethnic: '',
  });

  // Track last loaded province to prevent infinite loops
  let lastLoadedProvince = $state('');
  // Track which patient we've initialized the form for
  let initializedPatientId = $state(null);

  const prefixOptions = [
    { value: 'Mr', label: 'Mr' },
    { value: 'Mrs', label: 'Mrs' },
    { value: 'Ms', label: 'Ms' },
    { value: 'Dr', label: 'Dr' },
  ];

  const provinceOptions = $derived(
    provinces.map((p) => ({
      value: p.AreaCode || p.value || p.code || p.Code || p.id || p.ID || '',
      label: p.AreaName || p.label || p.name || p.Name || p.description || p.Description || ''
    }))
  );

  const cityOptions = $derived(
    cities.map((c) => ({
      value: c.AreaCode || c.value || c.code || c.Code || c.id || c.ID || '',
      label: c.AreaName || c.label || c.name || c.Name || c.description || c.Description || ''
    }))
  );

  const isEdit = $derived(!!patient);

  onMount(async () => {
    await loadProvinces();
  });

  $effect(() => {
    const currentPatientId = patient?.InternalPID || null;
    
    if (open && patient && !patientLoading && provinces.length > 0 && initializedPatientId !== currentPatientId) {
      // Edit mode - populate form (only when provinces are loaded and for a new patient)
      initializedPatientId = currentPatientId;
      const patientProvince = patient.Province || '';
      const patientCity = patient.City || '';

      formData = {
        InternalPID: patient.InternalPID,
        PatientID: patient.PatientID || '',
        Prefix: patient.Prefix || '',
        NameFirst: patient.NameFirst || '',
        NameMiddle: patient.NameMiddle || '',
        NameLast: patient.NameLast || '',
        NameMaiden: patient.NameMaiden || '',
        Suffix: patient.Suffix || '',
        Sex: patient.Sex || '',
        Birthdate: patient.Birthdate ? patient.Birthdate.split('T')[0] : '',
        PlaceOfBirth: patient.PlaceOfBirth || '',
        Citizenship: patient.Citizenship || '',
        Street_1: patient.Street_1 || '',
        Street_2: patient.Street_2 || '',
        Street_3: patient.Street_3 || '',
        Province: patientProvince,
        City: patientCity, // Set immediately, will be validated once cities load
        ZIP: patient.ZIP || '',
        Country: patient.Country || '',
        Phone: patient.Phone || '',
        MobilePhone: patient.MobilePhone || '',
        EmailAddress1: patient.EmailAddress1 || '',
        EmailAddress2: patient.EmailAddress2 || '',
        Race: patient.Race || '',
        MaritalStatus: patient.MaritalStatus || '',
        Religion: patient.Religion || '',
        Ethnic: patient.Ethnic || '',
      };
      
      // Load cities for this province
      lastLoadedProvince = patientProvince;
      if (patientProvince) {
        loadCities(patientProvince);
      }
    } else if (open && !patient && !patientLoading && initializedPatientId !== 'create') {
      // Create mode - reset form
      initializedPatientId = 'create';
      formData = {
        InternalPID: null,
        PatientID: '',
        Prefix: '',
        NameFirst: '',
        NameMiddle: '',
        NameLast: '',
        NameMaiden: '',
        Suffix: '',
        Sex: '',
        Birthdate: '',
        PlaceOfBirth: '',
        Citizenship: '',
        Street_1: '',
        Street_2: '',
        Street_3: '',
        Province: '',
        City: '',
        ZIP: '',
        Country: '',
        Phone: '',
        MobilePhone: '',
        EmailAddress1: '',
        EmailAddress2: '',
        Race: '',
        MaritalStatus: '',
        Religion: '',
        Ethnic: '',
      };
      cities = [];
      lastLoadedProvince = '';
    } else if (!open) {
      // Reset initialization when modal closes
      initializedPatientId = null;
    }
  });

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

  async function loadCities(provinceCode) {
    if (!provinceCode) {
      cities = [];
      return;
    }
    try {
      const response = await fetchCities(provinceCode);
      cities = Array.isArray(response.data) ? response.data : [];
    } catch (err) {
      console.error('Failed to load cities:', err);
      cities = [];
    }
  }

  function validateForm() {
    const errors = {};
    if (!formData.PatientID?.trim()) {
      errors.PatientID = 'Patient ID is required';
    }
    if (!formData.NameFirst?.trim()) {
      errors.NameFirst = 'First name is required';
    }
    if (!formData.Sex) {
      errors.Sex = 'Sex is required';
    }
    if (!formData.Birthdate) {
      errors.Birthdate = 'Birthdate is required';
    }
    formErrors = errors;
    return Object.keys(errors).length === 0;
  }

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

    saving = true;
    try {
      const payload = {
        ...formData,
        Birthdate: formData.Birthdate ? new Date(formData.Birthdate).toISOString() : undefined,
      };

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

      if (isEdit) {
        await updatePatient(payload.InternalPID || patient?.InternalPID, payload);
        toastSuccess('Patient updated successfully');
      } else {
        await createPatient(payload);
        toastSuccess('Patient created successfully');
      }
      open = false;
      onSave?.();
    } catch (err) {
      // Show API validation errors on modal
      if (err.messages && typeof err.messages === 'object') {
        formErrors = err.messages;
      } else {
        formErrors = { general: err.message || 'Failed to save patient' };
      }
    } finally {
      saving = false;
    }
  }

  $effect(() => {
    const province = formData.Province;
    if (province && province !== lastLoadedProvince) {
      lastLoadedProvince = province;
      // Load cities first, then clear city (prevents empty string display during loading)
      loadCities(province).then(() => {
        if (initializedPatientId !== null) {
          formData.City = '';
        }
      });
    } else if (!province) {
      cities = [];
      lastLoadedProvince = '';
      if (initializedPatientId !== null) {
        formData.City = '';
      }
    }
  });
</script>

<Modal
  bind:open
  title={isEdit ? 'Edit Patient' : 'Add Patient'}
  size="lg"
>
  {#if patientLoading}
    <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-3" onsubmit={(e) => e.preventDefault()}>
    <!-- Error Alert -->
    {#if Object.keys(formErrors).length > 0}
      <div class="alert alert-error alert-sm">
        <div class="flex flex-col">
          {#each Object.entries(formErrors) as [field, msg]}
            <span class="text-sm">{field}: {msg}</span>
          {/each}
        </div>
      </div>
    {/if}
    <!-- DaisyUI Tabs -->
    <div class="tabs tabs-bordered">
      <button
        type="button"
        class="tab tab-lg {activeTab === 'personal' ? 'tab-active' : ''}"
        onclick={() => activeTab = 'personal'}
      >
        <User class="w-4 h-4 mr-2" />
        Personal Info
      </button>
      <button
        type="button"
        class="tab tab-lg {activeTab === 'location' ? 'tab-active' : ''}"
        onclick={() => activeTab = 'location'}
      >
        <MapPin class="w-4 h-4 mr-2" />
        Location & Contact
      </button>
    </div>

    <!-- Personal Info Tab (Basic + Demographics) -->
    {#if activeTab === 'personal'}
      <div class="space-y-3">
        <!-- Basic Info Section -->
        <div>
          <h4 class="font-medium text-gray-700 mb-4">Basic Information</h4>
          <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={isEdit}
              />
              {#if formErrors.PatientID}
                <span class="text-error text-sm mt-1">{formErrors.PatientID}</span>
              {/if}
            </div>

            <SelectDropdown
              label="Prefix"
              name="prefix"
              bind:value={formData.Prefix}
              options={prefixOptions}
              placeholder="Select..."
            />
          </div>

          <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
            <div class="form-control">
              <label class="label" for="nameFirst">
                <span class="label-text font-medium">First Name</span>
                <span class="label-text-alt text-error">*</span>
              </label>
              <input
                id="nameFirst"
                type="text"
                class="input input-sm input-bordered w-full"
                class:input-error={formErrors.NameFirst}
                bind:value={formData.NameFirst}
                placeholder="Enter first name"
              />
              {#if formErrors.NameFirst}
                <span class="text-error text-sm mt-1">{formErrors.NameFirst}</span>
              {/if}
            </div>

            <div class="form-control">
              <label class="label" for="nameMiddle">
                <span class="label-text font-medium">Middle Name</span>
              </label>
              <input
                id="nameMiddle"
                type="text"
                class="input input-sm input-bordered w-full"
                bind:value={formData.NameMiddle}
                placeholder="Enter middle name"
              />
            </div>

            <div class="form-control">
              <label class="label" for="nameLast">
                <span class="label-text font-medium">Last Name</span>
              </label>
              <input
                id="nameLast"
                type="text"
                class="input input-sm input-bordered w-full"
                bind:value={formData.NameLast}
                placeholder="Enter last name"
              />
            </div>
          </div>

          <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
            <div class="form-control">
              <label class="label" for="nameMaiden">
                <span class="label-text font-medium">Maiden Name</span>
              </label>
              <input
                id="nameMaiden"
                type="text"
                class="input input-sm input-bordered w-full"
                bind:value={formData.NameMaiden}
                placeholder="Enter maiden name"
              />
            </div>

            <div class="form-control">
              <label class="label" for="suffix">
                <span class="label-text font-medium">Suffix</span>
              </label>
              <input
                id="suffix"
                type="text"
                class="input input-sm input-bordered w-full"
                bind:value={formData.Suffix}
                placeholder="Enter suffix (e.g., Jr, Sr, III)"
              />
            </div>
          </div>

          <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
            <SelectDropdown
                label="Sex"
                name="sex"
                bind:value={formData.Sex}
                valueSetKey="sex"
                placeholder="Select sex..."
                required={true}
                error={formErrors.Sex}
              />

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

            <div class="form-control">
              <label class="label" for="placeOfBirth">
                <span class="label-text font-medium">Place of Birth</span>
              </label>
              <input
                id="placeOfBirth"
                type="text"
                class="input input-sm input-bordered w-full"
                bind:value={formData.PlaceOfBirth}
                placeholder="Enter place of birth"
              />
            </div>
          </div>
        </div>

        <!-- Demographics Section -->
        <div class="border-t border-base-200 pt-6">
          <h4 class="font-medium text-gray-700 mb-4">Demographics</h4>
          <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
            <SelectDropdown
              label="Race"
              name="race"
              bind:value={formData.Race}
              valueSetKey="race"
              placeholder="Select race..."
            />

            <SelectDropdown
              label="Marital Status"
              name="maritalStatus"
              bind:value={formData.MaritalStatus}
              valueSetKey="marital_status"
              placeholder="Select marital status..."
            />

            <SelectDropdown
              label="Religion"
              name="religion"
              bind:value={formData.Religion}
              valueSetKey="religion"
              placeholder="Select religion..."
            />
          </div>

          <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
            <SelectDropdown
              label="Ethnicity"
              name="ethnic"
              bind:value={formData.Ethnic}
              valueSetKey="ethnic"
              placeholder="Select ethnicity..."
            />

            <div class="form-control">
              <label class="label" for="citizenship">
                <span class="label-text font-medium">Citizenship</span>
              </label>
              <input
                id="citizenship"
                type="text"
                class="input input-sm input-bordered w-full"
                bind:value={formData.Citizenship}
                placeholder="Enter citizenship"
              />
            </div>
          </div>
        </div>
      </div>
    {/if}

    <!-- Location & Contact Tab -->
    {#if activeTab === 'location'}
      <div class="space-y-3">
        <!-- Address Section -->
        <div>
          <h4 class="font-medium text-gray-700 mb-4">Address Information</h4>

          <div class="form-control mb-4">
            <label class="label" for="street1">
              <span class="label-text font-medium">Street Address</span>
            </label>
            <input
              id="street1"
              type="text"
              class="input input-sm input-bordered w-full"
              bind:value={formData.Street_1}
              placeholder="Enter street address"
            />
          </div>

          <div class="form-control mb-4">
            <label class="label" for="street2">
              <span class="label-text font-medium">Street Address Line 2</span>
            </label>
            <input
              id="street2"
              type="text"
              class="input input-sm input-bordered w-full"
              bind:value={formData.Street_2}
              placeholder="Enter street address line 2"
            />
          </div>

          <div class="form-control mb-4">
            <label class="label" for="street3">
              <span class="label-text font-medium">Street Address Line 3</span>
            </label>
            <input
              id="street3"
              type="text"
              class="input input-sm input-bordered w-full"
              bind:value={formData.Street_3}
              placeholder="Enter street address line 3"
            />
          </div>

          <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
            <SelectDropdown
              label="Province"
              name="province"
              bind:value={formData.Province}
              options={provinceOptions}
              placeholder="Select province..."
            />

            <SelectDropdown
              label="City"
              name="city"
              bind:value={formData.City}
              options={cityOptions}
              placeholder={formData.Province ? "Select city..." : "Select province first"}
              disabled={!formData.Province}
            />

            <div class="form-control">
              <label class="label" for="zip">
                <span class="label-text font-medium">ZIP Code</span>
              </label>
              <input
                id="zip"
                type="text"
                class="input input-sm input-bordered w-full"
                bind:value={formData.ZIP}
                placeholder="Enter ZIP code"
              />
            </div>
          </div>

          <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-4">
            <SelectDropdown
              label="Country"
              name="country"
              bind:value={formData.Country}
              valueSetKey="country"
              placeholder="Select country..."
            />
          </div>
        </div>

        <!-- Contact Section -->
        <div class="border-t border-base-200 pt-6">
          <h4 class="font-medium text-gray-700 mb-4">Contact Information</h4>
          
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div class="form-control">
              <label class="label" for="phone">
                <span class="label-text font-medium">Phone</span>
              </label>
              <input
                id="phone"
                type="tel"
                class="input input-sm input-bordered w-full"
                bind:value={formData.Phone}
                placeholder="Enter phone number"
              />
            </div>

            <div class="form-control">
              <label class="label" for="mobilePhone">
                <span class="label-text font-medium">Mobile Phone</span>
              </label>
              <input
                id="mobilePhone"
                type="tel"
                class="input input-sm input-bordered w-full"
                bind:value={formData.MobilePhone}
                placeholder="Enter mobile number"
              />
            </div>
          </div>

          <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
            <div class="form-control">
              <label class="label" for="email1">
                <span class="label-text font-medium">Email Address</span>
              </label>
              <input
                id="email1"
                type="email"
                class="input input-sm input-bordered w-full"
                bind:value={formData.EmailAddress1}
                placeholder="Enter email address"
              />
            </div>

            <div class="form-control">
              <label class="label" for="email2">
                <span class="label-text font-medium">Secondary Email</span>
              </label>
              <input
                id="email2"
                type="email"
                class="input input-sm input-bordered w-full"
                bind:value={formData.EmailAddress2}
                placeholder="Enter secondary email"
              />
            </div>
          </div>
        </div>
      </div>
    {/if}
  </form>
  {/if}
  {#snippet footer()}
    {#if patientLoading}
      <div class="flex justify-end gap-2">
        <button class="btn btn-ghost" disabled type="button">Cancel</button>
        <button class="btn btn-primary" disabled type="button">Loading...</button>
      </div>
    {:else}
    <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>
    {/if}
  {/snippet}
</Modal>
