<!-- [DEF:MappingManagement:Component] -->
<!--
@SEMANTICS: mapping, management, database, fuzzy-matching
@PURPOSE:   Page for managing database mappings between environments.
@LAYER:     Page
@RELATION:  USES -> EnvSelector
@RELATION:  USES -> MappingTable

@INVARIANT: Mappings are saved to the backend for persistence.
-->

<script lang="ts">
  // [SECTION: IMPORTS]
  import { onMount } from 'svelte';
  import EnvSelector from '../../../components/EnvSelector.svelte';
  import MappingTable from '../../../components/MappingTable.svelte';
  // [/SECTION]

  // [SECTION: STATE]
  let environments = [];
  let sourceEnvId = "";
  let targetEnvId = "";
  let sourceDatabases = [];
  let targetDatabases = [];
  let mappings = [];
  let suggestions = [];
  let loading = true;
  let fetchingDbs = false;
  let error = "";
  let success = "";
  // [/SECTION]

  // [DEF:fetchEnvironments:Function]
  // @PURPOSE: Fetches the list of environments.
  async function fetchEnvironments() {
    try {
      const response = await fetch('/api/environments');
      if (!response.ok) throw new Error('Failed to fetch environments');
      environments = await response.json();
    } catch (e) {
      error = e.message;
    } finally {
      loading = false;
    }
  }
  // [/DEF:fetchEnvironments:Function]

  onMount(fetchEnvironments);

  // [DEF:fetchDatabases:Function]
  /**
   * @purpose Fetches databases from both environments and gets suggestions.
   */
  async function fetchDatabases() {
    if (!sourceEnvId || !targetEnvId) return;
    fetchingDbs = true;
    error = "";
    success = "";
    
    try {
      const [srcRes, tgtRes, mapRes, sugRes] = await Promise.all([
        fetch(`/api/environments/${sourceEnvId}/databases`),
        fetch(`/api/environments/${targetEnvId}/databases`),
        fetch(`/api/mappings?source_env_id=${sourceEnvId}&target_env_id=${targetEnvId}`),
        fetch(`/api/mappings/suggest`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ source_env_id: sourceEnvId, target_env_id: targetEnvId })
        })
      ]);

      if (!srcRes.ok || !tgtRes.ok) throw new Error('Failed to fetch databases from environments');
      
      sourceDatabases = await srcRes.json();
      targetDatabases = await tgtRes.json();
      mappings = await mapRes.json();
      suggestions = await sugRes.json();
    } catch (e) {
      error = e.message;
    } finally {
      fetchingDbs = false;
    }
  }
  // [/DEF:fetchDatabases:Function]

  // [DEF:handleUpdate:Function]
  /**
   * @purpose Saves a mapping to the backend.
   */
  async function handleUpdate(event: CustomEvent) {
    const { sourceUuid, targetUuid } = event.detail;
    const sDb = sourceDatabases.find(d => d.uuid === sourceUuid);
    const tDb = targetDatabases.find(d => d.uuid === targetUuid);
    
    if (!sDb || !tDb) return;

    try {
      const response = await fetch('/api/mappings', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          source_env_id: sourceEnvId,
          target_env_id: targetEnvId,
          source_db_uuid: sourceUuid,
          target_db_uuid: targetUuid,
          source_db_name: sDb.database_name,
          target_db_name: tDb.database_name
        })
      });

      if (!response.ok) throw new Error('Failed to save mapping');
      
      const savedMapping = await response.json();
      mappings = [...mappings.filter(m => m.source_db_uuid !== sourceUuid), savedMapping];
      success = "Mapping saved successfully";
    } catch (e) {
      error = e.message;
    }
  }
  // [/DEF:handleUpdate:Function]
</script>

<!-- [SECTION: TEMPLATE] -->
<div class="max-w-6xl mx-auto p-6">
  <h1 class="text-2xl font-bold mb-6">Database Mapping Management</h1>

  {#if loading}
    <p>Loading environments...</p>
  {:else}
    <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
      <EnvSelector
        label="Source Environment"
        bind:selectedId={sourceEnvId}
        {environments}
        on:change={() => { sourceDatabases = []; mappings = []; suggestions = []; }}
      />
      <EnvSelector
        label="Target Environment"
        bind:selectedId={targetEnvId}
        {environments}
        on:change={() => { targetDatabases = []; mappings = []; suggestions = []; }}
      />
    </div>

    <div class="mb-8">
      <button
        on:click={fetchDatabases}
        disabled={!sourceEnvId || !targetEnvId || sourceEnvId === targetEnvId || fetchingDbs}
        class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:bg-gray-400"
      >
        {fetchingDbs ? 'Fetching...' : 'Fetch Databases & Suggestions'}
      </button>
    </div>

    {#if error}
      <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
        {error}
      </div>
    {/if}

    {#if success}
      <div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-4">
        {success}
      </div>
    {/if}

    {#if sourceDatabases.length > 0}
      <MappingTable
        {sourceDatabases}
        {targetDatabases}
        {mappings}
        {suggestions}
        on:update={handleUpdate}
      />
    {:else if !fetchingDbs && sourceEnvId && targetEnvId}
      <p class="text-gray-500 italic">Select environments and click "Fetch Databases" to start mapping.</p>
    {/if}
  {/if}
</div>
<!-- [/SECTION] -->

<style>
  /* Page specific styles */
</style>

<!-- [/DEF:MappingManagement:Component] -->
