<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';

  /** @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 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);
        toastSuccess('Patient updated successfully');
      } else {
        await createPatient(payload);
        toastSuccess('Patient created successfully');
      }
      open = false;
      onSave?.();
    } catch (err) {
      toastError(err.message || 'Failed to save patient');
    } finally {
      saving = false;
    }
  }

  $effect(() => {
    const province = formData.Province;
    if (province && province !== lastLoadedProvince) {
      lastLoadedProvince = province;
      // Clear city when province changes (only after form is initialized)
      if (initializedPatientId !== null) {
        formData.City = '';
      }
      loadCities(province);
    } 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-6" onsubmit={(e) => e.preventDefault()}>
    <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-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">
      <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-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-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-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">
      <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-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-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">
      <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-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-bordered w-full"
          bind:value={formData.PlaceOfBirth}
          placeholder="Enter place of birth"
        />
      </div>
    </div>

    <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 mb-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">
        <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-bordered w-full"
            bind:value={formData.Citizenship}
            placeholder="Enter citizenship"
          />
        </div>
      </div>
    </div>

    <div class="border-t border-base-200 pt-6">
      <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-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-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-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-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>

    <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-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-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-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-bordered w-full"
            bind:value={formData.EmailAddress2}
            placeholder="Enter secondary email"
          />
        </div>
      </div>
    </div>
  </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>
