<script>
  import { onMount } from 'svelte';
  import { fetchGeographicalAreas, fetchProvinces, fetchCities } from '$lib/api/geography.js';
  import { success as toastSuccess, error as toastError } from '$lib/utils/toast.js';
  import DataTable from '$lib/components/DataTable.svelte';
  import SelectDropdown from '$lib/components/SelectDropdown.svelte';
  import HelpTooltip from '$lib/components/HelpTooltip.svelte';
  import {
    ArrowLeft,
    MapPin,
    Globe,
    Building2,
    Search,
    Info,
    MapPinned,
    TreePine,
    Mountain,
    Waves,
    Home,
    Building,
    LandPlot,
    Map,
    AlertCircle,
    Database
  } from 'lucide-svelte';

  let loading = $state(false);
  let loadingMessage = $state('Loading...');
  let activeTab = $state('provinces');
  let areas = $state([]);
  let provinces = $state([]);
  let cities = $state([]);
  let selectedProvince = $state('');

  // Search states for each tab
  let provinceSearch = $state('');
  let citySearch = $state('');
  let areaSearch = $state('');

  // Area class to icon mapping
  const areaClassIcons = {
    'Province': MapPinned,
    'Regency': Building,
    'District': LandPlot,
    'Village': Home,
    'Country': Globe,
    'State': Map,
    'City': Building2,
    'Island': TreePine,
    'Mountain': Mountain,
    'Coastal': Waves,
  };

  const areaColumns = [
    { key: 'AreaGeoID', label: 'ID', class: 'font-medium w-20' },
    { key: 'AreaCode', label: 'Code', class: 'w-24' },
    { key: 'AreaName', label: 'Name' },
    { key: 'Class', label: 'Class', class: 'w-32' },
    { key: 'Parent', label: 'Parent Area' },
  ];

  const provinceColumns = [
    { key: 'value', label: 'ID', class: 'font-medium w-24' },
    { key: 'label', label: 'Province Name' },
  ];

  const cityColumns = [
    { key: 'value', label: 'ID', class: 'font-medium w-24' },
    { key: 'label', label: 'City Name' },
  ];

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

  async function loadAreas() {
    loading = true;
    loadingMessage = 'Loading geographical areas...';
    try {
      const response = await fetchGeographicalAreas();
      areas = response.data || [];
    } catch (err) {
      toastError(err.message || 'Failed to load geographical areas');
      areas = [];
    } finally {
      loading = false;
    }
  }

  async function loadProvinces() {
    loading = true;
    loadingMessage = 'Loading provinces...';
    try {
      const response = await fetchProvinces();
      provinces = Array.isArray(response) ? response : (Array.isArray(response.data) ? response.data : []);
    } catch (err) {
      toastError(err.message || 'Failed to load provinces');
      provinces = [];
    } finally {
      loading = false;
    }
  }

  async function loadCities() {
    loading = true;
    loadingMessage = selectedProvince
      ? 'Loading cities for selected province...'
      : 'Loading all cities...';
    try {
      const provinceId = selectedProvince || null;
      const response = await fetchCities(provinceId);
      cities = Array.isArray(response) ? response : (Array.isArray(response.data) ? response.data : []);
    } catch (err) {
      toastError(err.message || 'Failed to load cities');
      cities = [];
    } finally {
      loading = false;
    }
  }

  function handleTabChange(tab) {
    activeTab = tab;
    // Reset search when changing tabs
    provinceSearch = '';
    citySearch = '';
    areaSearch = '';

    if (tab === 'areas' && areas.length === 0) {
      loadAreas();
    } else if (tab === 'cities' && cities.length === 0) {
      loadCities();
    }
  }

  function getAreaClassIcon(className) {
    if (!className) return MapPin;
    const IconComponent = areaClassIcons[className];
    return IconComponent || MapPin;
  }

  const provinceOptions = $derived(
    provinces.map((p) => ({ value: p.value, label: p.label }))
  );

  // Filtered data based on search
  const filteredProvinces = $derived(
    provinceSearch.trim()
      ? provinces.filter(p =>
          p.label.toLowerCase().includes(provinceSearch.toLowerCase())
        )
      : provinces
  );

  const filteredCities = $derived(
    citySearch.trim()
      ? cities.filter(c =>
          c.label.toLowerCase().includes(citySearch.toLowerCase())
        )
      : cities
  );

  const filteredAreas = $derived(
    areaSearch.trim()
      ? areas.filter(a =>
          (a.AreaName && a.AreaName.toLowerCase().includes(areaSearch.toLowerCase())) ||
          (a.AreaCode && a.AreaCode.toLowerCase().includes(areaSearch.toLowerCase())) ||
          (a.Class && a.Class.toLowerCase().includes(areaSearch.toLowerCase()))
        )
      : areas
  );

  const selectedProvinceLabel = $derived(
    selectedProvince
      ? provinces.find(p => String(p.value) === String(selectedProvince))?.label
      : null
  );

  // Reload cities when province filter changes
  $effect(() => {
    if (activeTab === 'cities') {
      loadCities();
    }
  });
</script>

<div class="p-6">
  <div class="flex items-center gap-4 mb-6">
    <a href="/master-data" class="btn btn-ghost btn-circle">
      <ArrowLeft class="w-5 h-5" />
    </a>
    <div class="flex-1">
      <div class="flex items-center gap-2">
        <h1 class="text-3xl font-bold text-gray-800">Geography</h1>
        <HelpTooltip
          title="Geography Data"
          text="Geography data is used for patient address management throughout the system. This includes province, city, and detailed area information."
          position="right"
        />
      </div>
      <p class="text-gray-600">View geographical areas, provinces, and cities</p>
    </div>
  </div>

  <!-- Info Banner -->
  <div class="alert alert-info mb-6">
    <Info class="w-5 h-5 shrink-0" />
    <div>
      <span class="font-medium">Reference Data</span>
      <p class="text-sm opacity-80">
        Geography data is read-only reference information used for patient address management.
        This data is maintained by system administrators and synchronized with national standards.
      </p>
    </div>
  </div>

  <div class="tabs tabs-boxed mb-6">
    <button
      class="tab gap-2"
      class:tab-active={activeTab === 'provinces'}
      onclick={() => handleTabChange('provinces')}
    >
      <MapPin class="w-4 h-4" />
      Provinces
      {#if provinces.length > 0}
        <span class="badge badge-sm badge-primary">{provinces.length}</span>
      {/if}
    </button>
    <button
      class="tab gap-2"
      class:tab-active={activeTab === 'cities'}
      onclick={() => handleTabChange('cities')}
    >
      <Building2 class="w-4 h-4" />
      Cities
    </button>
    <button
      class="tab gap-2"
      class:tab-active={activeTab === 'areas'}
      onclick={() => handleTabChange('areas')}
    >
      <Globe class="w-4 h-4" />
      All Areas
    </button>
  </div>

  {#if activeTab === 'provinces'}
    <div class="space-y-4">
      <!-- Tab Description -->
      <div class="flex items-start gap-2 text-sm text-gray-600 bg-base-200 p-3 rounded-lg">
        <MapPin class="w-4 h-4 mt-0.5 shrink-0" />
        <div class="flex-1">
          <span class="font-medium">Provinces</span> are the top-level administrative divisions.
          Cities and areas are organized hierarchically under provinces.
          <HelpTooltip
            text="Provinces form the first level of the geographical hierarchy. Each city belongs to exactly one province."
            position="right"
          />
        </div>
      </div>

      <!-- Search -->
      <div class="relative">
        <Search class="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
        <input
          type="text"
          placeholder="Search provinces by name..."
          class="input input-bordered w-full pl-10"
          bind:value={provinceSearch}
        />
      </div>

      <div class="bg-base-100 rounded-lg shadow border border-base-200">
        {#if loading}
          <div class="text-center py-12">
            <span class="loading loading-spinner loading-lg text-primary"></span>
            <p class="text-gray-500 mt-4">{loadingMessage}</p>
          </div>
        {:else if filteredProvinces.length === 0}
          <div class="text-center py-12">
            {#if provinceSearch.trim()}
              <Search class="w-12 h-12 mx-auto text-gray-300 mb-3" />
              <p class="text-gray-500">No provinces match "{provinceSearch}"</p>
              <button class="btn btn-sm btn-ghost mt-2" onclick={() => provinceSearch = ''}>
                Clear search
              </button>
            {:else}
              <MapPin class="w-12 h-12 mx-auto text-gray-300 mb-3" />
              <p class="text-gray-500">No provinces found</p>
            {/if}
          </div>
        {:else}
          <DataTable
            columns={provinceColumns}
            data={filteredProvinces}
            loading={false}
            emptyMessage="No provinces found"
            hover={true}
            bordered={false}
          />
        {/if}
      </div>
    </div>

  {:else if activeTab === 'cities'}
    <div class="space-y-4">
      <!-- Tab Description -->
      <div class="flex items-start gap-2 text-sm text-gray-600 bg-base-200 p-3 rounded-lg">
        <Building2 class="w-4 h-4 mt-0.5 shrink-0" />
        <div class="flex-1">
          <span class="font-medium">Cities</span> are the second-level administrative divisions within provinces.
          Use the filter below to view cities for a specific province.
          <HelpTooltip
            text="Cities are organized hierarchically under provinces. When you select a province, only cities within that province are displayed."
            position="right"
          />
        </div>
      </div>

      <!-- Province Filter -->
      <div class="bg-base-200 p-4 rounded-lg">
        <div class="flex items-start gap-4">
          <div class="flex-1">
            <SelectDropdown
              label="Filter by Province"
              name="province"
              bind:value={selectedProvince}
              options={provinceOptions}
              placeholder="-- All Provinces --"
            />
          </div>
          {#if selectedProvince && selectedProvinceLabel}
            <div class="pt-8">
              <span class="badge badge-primary badge-lg">
                {filteredCities.length} cities in {selectedProvinceLabel}
              </span>
            </div>
          {/if}
        </div>
        <p class="text-xs text-gray-500 mt-2">
          Select a province to filter cities, or leave empty to view all cities
        </p>
      </div>

      <!-- Search -->
      <div class="relative">
        <Search class="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
        <input
          type="text"
          placeholder={selectedProvince
            ? `Search cities in ${selectedProvinceLabel}...`
            : "Search cities by name..."
          }
          class="input input-bordered w-full pl-10"
          bind:value={citySearch}
        />
      </div>

      <div class="bg-base-100 rounded-lg shadow border border-base-200">
        {#if loading}
          <div class="text-center py-12">
            <span class="loading loading-spinner loading-lg text-primary"></span>
            <p class="text-gray-500 mt-4">{loadingMessage}</p>
          </div>
        {:else if filteredCities.length === 0}
          <div class="text-center py-12">
            {#if citySearch.trim()}
              <Search class="w-12 h-12 mx-auto text-gray-300 mb-3" />
              <p class="text-gray-500">No cities match "{citySearch}"</p>
              <button class="btn btn-sm btn-ghost mt-2" onclick={() => citySearch = ''}>
                Clear search
              </button>
            {:else if selectedProvince}
              <Building2 class="w-12 h-12 mx-auto text-gray-300 mb-3" />
              <p class="text-gray-500">No cities found for {selectedProvinceLabel}</p>
              <p class="text-sm text-gray-400 mt-1">Try selecting a different province</p>
            {:else}
              <Building2 class="w-12 h-12 mx-auto text-gray-300 mb-3" />
              <p class="text-gray-500">No cities found</p>
            {/if}
          </div>
        {:else}
          <DataTable
            columns={cityColumns}
            data={filteredCities}
            loading={false}
            emptyMessage="No cities found"
            hover={true}
            bordered={false}
          />
        {/if}
      </div>
    </div>

  {:else if activeTab === 'areas'}
    <div class="space-y-4">
      <!-- Tab Description -->
      <div class="flex items-start gap-2 text-sm text-gray-600 bg-base-200 p-3 rounded-lg">
        <Globe class="w-4 h-4 mt-0.5 shrink-0" />
        <div class="flex-1">
          <span class="font-medium">All Areas</span> shows the complete geographical hierarchy including
          provinces, cities, districts, and villages with their relationships.
          <HelpTooltip
            text="Areas represent the complete geographical hierarchy from provinces down to villages. Each area has a class indicating its level in the hierarchy and may have a parent area."
            position="right"
          />
        </div>
      </div>

      <!-- Search -->
      <div class="relative">
        <Search class="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
        <input
          type="text"
          placeholder="Search areas by name, code, or class..."
          class="input input-bordered w-full pl-10"
          bind:value={areaSearch}
        />
      </div>

      <div class="bg-base-100 rounded-lg shadow border border-base-200">
        {#if loading}
          <div class="text-center py-12">
            <span class="loading loading-spinner loading-lg text-primary"></span>
            <p class="text-gray-500 mt-4">{loadingMessage}</p>
          </div>
        {:else if filteredAreas.length === 0}
          <div class="text-center py-12">
            {#if areaSearch.trim()}
              <Search class="w-12 h-12 mx-auto text-gray-300 mb-3" />
              <p class="text-gray-500">No areas match "{areaSearch}"</p>
              <button class="btn btn-sm btn-ghost mt-2" onclick={() => areaSearch = ''}>
                Clear search
              </button>
            {:else}
              <Globe class="w-12 h-12 mx-auto text-gray-300 mb-3" />
              <p class="text-gray-500">No geographical areas found</p>
            {/if}
          </div>
        {:else}
          <DataTable
            columns={areaColumns}
            data={filteredAreas}
            loading={false}
            emptyMessage="No geographical areas found"
            hover={true}
            bordered={false}
          >
            {#snippet cell({ column, row, value })}
              {#if column.key === 'Class'}
                {@const IconComponent = getAreaClassIcon(value)}
                <div class="flex items-center gap-2">
                  <IconComponent class="w-4 h-4 text-primary" />
                  <span>{value}</span>
                </div>
              {:else}
                {value}
              {/if}
            {/snippet}
          </DataTable>
        {/if}
      </div>

      <!-- Area Class Legend -->
      {#if filteredAreas.length > 0}
        <div class="bg-base-200 p-4 rounded-lg">
          <h4 class="text-sm font-medium mb-3 flex items-center gap-2">
            <Map class="w-4 h-4" />
            Area Class Types
          </h4>
          <div class="flex flex-wrap gap-2">
            {#each Object.entries(areaClassIcons) as [className, IconComponent] (className)}
              <div class="badge badge-outline gap-1">
                <IconComponent class="w-3 h-3" />
                {className}
              </div>
            {/each}
          </div>
        </div>
      {/if}
    </div>
  {/if}
</div>
