<?= $this->extend("v2/layout/main_layout"); ?>

<?= $this->section("content") ?>
<div x-data="valueSetManager()" x-init="init()">
  
  <!-- Page Header -->
  <div class="card-glass p-6 animate-fadeIn mb-6">
    <div class="flex items-center gap-4">
      <div class="w-14 h-14 rounded-2xl bg-gradient-to-br from-blue-600 to-indigo-800 flex items-center justify-center shadow-lg">
        <i class="fa-solid fa-layer-group text-2xl text-white"></i>
      </div>
      <div>
        <h2 class="text-2xl font-bold" style="color: rgb(var(--color-text));">Value Set Manager</h2>
        <p class="text-sm" style="color: rgb(var(--color-text-muted));">Manage value set categories and their items</p>
      </div>
    </div>
  </div>

  <!-- Two Column Layout with Independent Scrolling -->
  <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
    
    <!-- LEFT PANEL: ValueSetDef List -->
    <div class="card overflow-hidden flex flex-col" style="height: calc(100vh - 280px); min-height: 400px;">
      <!-- Left Panel Header -->
      <div class="p-4 border-b flex items-center justify-between" style="border-color: rgb(var(--color-border));">
        <div class="flex items-center gap-3">
          <div class="w-10 h-10 rounded-lg flex items-center justify-center" style="background: rgb(var(--color-primary));">
            <i class="fa-solid fa-layer-group text-white"></i>
          </div>
          <div>
            <h3 class="font-bold" style="color: rgb(var(--color-text));">Categories</h3>
            <p class="text-xs" style="color: rgb(var(--color-text-muted));">Value Set Definitions</p>
          </div>
        </div>
        <button class="btn btn-primary btn-sm" @click="showDefForm()">
          <i class="fa-solid fa-plus mr-1"></i> Add
        </button>
      </div>

      <!-- Search Bar -->
      <div class="p-3 border-b" style="border-color: rgb(var(--color-border));">
        <div class="relative">
          <i class="fa-solid fa-search absolute left-3 top-1/2 -translate-y-1/2 opacity-50 text-gray-400" style="z-index: 10;"></i>
          <input 
            type="text" 
            placeholder="Search categories..." 
            class="input input-sm w-full input-with-icon"
            x-model="defKeyword"
            @keyup.enter="fetchDefs()"
          />
        </div>
      </div>

      <!-- Loading State -->
      <div x-show="defLoading" class="p-12 text-center" x-cloak>
        <div class="spinner spinner-lg mx-auto mb-4"></div>
        <p style="color: rgb(var(--color-text-muted));">Loading categories...</p>
      </div>

      <!-- Def List Table -->
      <div class="overflow-y-auto flex-1" x-show="!defLoading" x-cloak>
        <table class="table">
          <thead>
            <tr>
              <th class="w-16">ID</th>
              <th>Category Name</th>
              <th class="w-20 text-center">Items</th>
              <th class="w-24 text-center">Actions</th>
            </tr>
          </thead>
          <tbody>
            <template x-if="!defList || defList.length === 0">
              <tr>
                <td colspan="4" class="text-center py-12">
                  <div class="flex flex-col items-center gap-2" style="color: rgb(var(--color-text-muted));">
                    <i class="fa-solid fa-folder-open text-4xl opacity-40"></i>
                    <p class="text-sm">No categories found</p>
                    <button class="btn btn-primary btn-sm mt-2" @click="showDefForm()">
                      <i class="fa-solid fa-plus mr-1"></i> Add Category
                    </button>
                  </div>
                </td>
              </tr>
            </template>

            <template x-for="def in defList" :key="def.VSetID">
              <tr 
                class="hover:bg-opacity-50 cursor-pointer transition-colors"
                :class="selectedDef?.VSetID === def.VSetID ? 'bg-primary/10' : ''"
                @click="selectDef(def)"
              >
                <td>
                  <span class="badge badge-ghost font-mono text-xs" x-text="def.VSetID || '-'"></span>
                </td>
                <td>
                  <div class="font-medium" style="color: rgb(var(--color-text));" x-text="def.VSName || '-'"></div>
                  <div class="text-xs opacity-50" x-text="def.VSDesc || ''"></div>
                </td>
                <td class="text-center">
                  <span class="badge badge-sm" x-text="(def.ItemCount || 0) + ' items'"></span>
                </td>
                <td class="text-center">
                  <div class="flex items-center justify-center gap-1" @click.stop>
                    <button class="btn btn-ghost btn-sm btn-square" @click="editDef(def.VSetID)" title="Edit">
                      <i class="fa-solid fa-pen text-sky-500"></i>
                    </button>
                    <button class="btn btn-ghost btn-sm btn-square" @click="confirmDeleteDef(def)" title="Delete">
                      <i class="fa-solid fa-trash" style="color: rgb(var(--color-error));"></i>
                    </button>
                  </div>
                </td>
              </tr>
            </template>
          </tbody>
        </table>
      </div>

      <!-- Left Panel Footer -->
      <div class="p-3 flex items-center justify-between text-xs" style="border-top: 1px solid rgb(var(--color-border));" x-show="defList && defList.length > 0">
        <span style="color: rgb(var(--color-text-muted));" x-text="defList.length + ' categories'"></span>
      </div>
    </div>

    <!-- RIGHT PANEL: ValueSet Items -->
    <div class="card overflow-hidden flex flex-col" style="height: calc(100vh - 280px); min-height: 400px;">
      <!-- Right Panel Header -->
      <div class="p-4 border-b flex items-center justify-between" style="border-color: rgb(var(--color-border));">
        <div class="flex items-center gap-3">
          <div class="w-10 h-10 rounded-lg flex items-center justify-center" style="background: rgb(var(--color-secondary));">
            <i class="fa-solid fa-list-ul text-white"></i>
          </div>
          <div>
            <h3 class="font-bold" style="color: rgb(var(--color-text));">Items</h3>
            <p class="text-xs" style="color: rgb(var(--color-text-muted));">
              <template x-if="selectedDef">
                <span x-text="selectedDef.VSName + ' Items'"></span>
              </template>
              <template x-if="!selectedDef">
                <span>Select a category to view items</span>
              </template>
            </p>
          </div>
        </div>
        <button 
          class="btn btn-primary btn-sm" 
          @click="showValueForm()"
          :disabled="!selectedDef"
        >
          <i class="fa-solid fa-plus mr-1"></i> Add Item
        </button>
      </div>

      <!-- Search Bar (Right Panel) -->
      <div class="p-3 border-b" style="border-color: rgb(var(--color-border));" x-show="selectedDef">
        <div class="relative">
          <i class="fa-solid fa-search absolute left-3 top-1/2 -translate-y-1/2 opacity-50 text-gray-400" style="z-index: 10;"></i>
          <input 
            type="text" 
            placeholder="Filter items..." 
            class="input input-sm w-full input-with-icon"
            x-model="valueKeyword"
            @keyup.enter="fetchValues()"
          />
        </div>
      </div>

      <!-- Empty State - No Selection -->
      <div x-show="!selectedDef" class="p-16 text-center" x-cloak>
        <div class="flex flex-col items-center gap-3" style="color: rgb(var(--color-text-muted));">
          <i class="fa-solid fa-hand-pointer text-5xl opacity-30"></i>
          <p class="text-lg font-medium">Select a category</p>
          <p class="text-sm opacity-60">Click on a category from the left panel to view and manage its items</p>
        </div>
      </div>

      <!-- Loading State -->
      <div x-show="valueLoading && selectedDef" class="p-12 text-center" x-cloak>
        <div class="spinner spinner-lg mx-auto mb-4"></div>
        <p style="color: rgb(var(--color-text-muted));">Loading items...</p>
      </div>

      <!-- Value List Table -->
      <div class="overflow-y-auto flex-1" x-show="!valueLoading && selectedDef" x-cloak>
        <table class="table">
          <thead>
            <tr>
              <th class="w-16">ID</th>
              <th>Value</th>
              <th>Description</th>
              <th class="w-16 text-center">Order</th>
              <th class="w-20 text-center">Actions</th>
            </tr>
          </thead>
          <tbody>
            <template x-if="!valueList || valueList.length === 0">
              <tr>
                <td colspan="5" class="text-center py-12">
                  <div class="flex flex-col items-center gap-2" style="color: rgb(var(--color-text-muted));">
                    <i class="fa-solid fa-inbox text-4xl opacity-40"></i>
                    <p class="text-sm">No items found</p>
                    <button class="btn btn-primary btn-sm mt-2" @click="showValueForm()">
                      <i class="fa-solid fa-plus mr-1"></i> Add First Item
                    </button>
                  </div>
                </td>
              </tr>
            </template>

            <template x-for="value in valueList" :key="value.VID">
              <tr class="hover:bg-opacity-50">
                <td>
                  <span class="badge badge-ghost font-mono text-xs" x-text="value.VID || '-'"></span>
                </td>
                <td>
                  <div class="font-medium" style="color: rgb(var(--color-text));" x-text="value.VValue || '-'"></div>
                </td>
                <td>
                  <span class="text-sm opacity-70" x-text="value.VDesc || '-'"></span>
                </td>
                <td class="text-center">
                  <span class="font-mono text-sm" x-text="value.VOrder || 0"></span>
                </td>
                <td class="text-center">
                  <div class="flex items-center justify-center gap-1">
                    <button class="btn btn-ghost btn-sm btn-square" @click="editValue(value.VID)" title="Edit">
                      <i class="fa-solid fa-pen text-sky-500"></i>
                    </button>
                    <button class="btn btn-ghost btn-sm btn-square" @click="confirmDeleteValue(value)" title="Delete">
                      <i class="fa-solid fa-trash" style="color: rgb(var(--color-error));"></i>
                    </button>
                  </div>
                </td>
              </tr>
            </template>
          </tbody>
        </table>
      </div>

      <!-- Right Panel Footer -->
      <div class="p-3 flex items-center justify-between text-xs" style="border-top: 1px solid rgb(var(--color-border));" x-show="valueList && valueList.length > 0 && selectedDef">
        <span style="color: rgb(var(--color-text-muted));" x-text="valueList.length + ' items'"></span>
      </div>
    </div>
  </div>

  <!-- Include Definition Form Dialog -->
  <?= $this->include('v2/master/valuesets/valuesetdef_dialog') ?>

  <!-- Include Value Form Dialog -->
  <?= $this->include('v2/master/valuesets/valueset_dialog') ?>

  <!-- Delete Category Confirmation Modal -->
  <div 
    x-show="showDeleteDefModal" 
    x-cloak
    class="modal-overlay"
    @click.self="showDeleteDefModal = false"
  >
    <div class="modal-content p-6 max-w-md">
      <h3 class="font-bold text-lg mb-4 flex items-center gap-2" style="color: rgb(var(--color-error));">
        <i class="fa-solid fa-exclamation-triangle"></i>
        Confirm Delete
      </h3>
      <p class="mb-6" style="color: rgb(var(--color-text));">
        Are you sure you want to delete category <strong x-text="deleteDefTarget?.VSName"></strong>?
        This will also delete all items in this category and cannot be undone.
      </p>
      <div class="flex gap-2">
        <button class="btn btn-ghost flex-1" @click="showDeleteDefModal = false">Cancel</button>
        <button class="btn flex-1" style="background: rgb(var(--color-error)); color: white;" @click="deleteDef()" :disabled="deletingDef">
          <span x-show="deletingDef" class="spinner spinner-sm"></span>
          <span x-show="!deletingDef">Delete</span>
        </button>
      </div>
    </div>
  </div>

  <!-- Delete Value Confirmation Modal -->
  <div 
    x-show="showDeleteValueModal" 
    x-cloak
    class="modal-overlay"
    @click.self="showDeleteValueModal = false"
  >
    <div class="modal-content p-6 max-w-md">
      <h3 class="font-bold text-lg mb-4 flex items-center gap-2" style="color: rgb(var(--color-error));">
        <i class="fa-solid fa-exclamation-triangle"></i>
        Confirm Delete
      </h3>
      <p class="mb-6" style="color: rgb(var(--color-text));">
        Are you sure you want to delete item <strong x-text="deleteValueTarget?.VValue"></strong>?
      </p>
      <div class="flex gap-2">
        <button class="btn btn-ghost flex-1" @click="showDeleteValueModal = false">Cancel</button>
        <button class="btn flex-1" style="background: rgb(var(--color-error)); color: white;" @click="deleteValue()" :disabled="deletingValue">
          <span x-show="deletingValue" class="spinner spinner-sm"></span>
          <span x-show="!deletingValue">Delete</span>
        </button>
      </div>
    </div>
  </div>

</div>
<?= $this->endSection() ?>

<?= $this->section("script") ?>
<script>
function valueSetManager() {
  return {
    // State - Definitions
    defLoading: false,
    defList: [],
    defKeyword: "",
    
    // State - Values
    valueLoading: false,
    valueList: [],
    valueKeyword: "",
    selectedDef: null,
    
    // Definition Form
    showDefModal: false,
    isEditingDef: false,
    savingDef: false,
    defErrors: {},
    defForm: {
      VSetID: null,
      VSName: "",
      VSDesc: "",
      SiteID: 1
    },
    
    // Value Form
    showValueModal: false,
    isEditingValue: false,
    savingValue: false,
    valueErrors: {},
    valueForm: {
      VID: null,
      VSetID: "",
      VOrder: 0,
      VValue: "",
      VDesc: "",
      SiteID: 1
    },
    
    // Delete Definition
    showDeleteDefModal: false,
    deleteDefTarget: null,
    deletingDef: false,
    
    // Delete Value
    showDeleteValueModal: false,
    deleteValueTarget: null,
    deletingValue: false,
    
    // Dropdown data
    defsList: [],
    
    // Lifecycle
    async init() {
      await this.fetchDefs();
    },
    
    // ==================== DEFINITION METHODS ====================
    
    async fetchDefs() {
      this.defLoading = true;
      try {
        const params = new URLSearchParams();
        if (this.defKeyword) params.append('param', this.defKeyword);
        
        const res = await fetch(`${BASEURL}api/valuesetdef?${params}`, {
          credentials: 'include'
        });
        if (!res.ok) throw new Error("HTTP error");
        const data = await res.json();
        this.defList = data.data || [];
        
        // Update selected def in list if exists
        if (this.selectedDef) {
          const updated = this.defList.find(d => d.VSetID === this.selectedDef.VSetID);
          if (updated) {
            this.selectedDef = updated;
          }
        }
      } catch (err) {
        console.error(err);
        this.defList = [];
        this.showToast('Failed to load categories', 'error');
      } finally {
        this.defLoading = false;
      }
    },
    
    showDefForm() {
      this.isEditingDef = false;
      this.defForm = {
        VSetID: null,
        VSName: "",
        VSDesc: "",
        SiteID: 1
      };
      this.defErrors = {};
      this.showDefModal = true;
    },
    
    async editDef(id) {
      this.isEditingDef = true;
      this.defErrors = {};
      try {
        const res = await fetch(`${BASEURL}api/valuesetdef/${id}`, {
          credentials: 'include'
        });
        const data = await res.json();
        if (data.data) {
          this.defForm = { ...this.defForm, ...data.data };
          this.showDefModal = true;
        }
      } catch (err) {
        console.error(err);
        this.showToast('Failed to load category data', 'error');
      }
    },
    
    validateDef() {
      const e = {};
      if (!this.defForm.VSName?.trim()) e.VSName = "Category name is required";
      this.defErrors = e;
      return Object.keys(e).length === 0;
    },
    
    closeDefModal() {
      this.showDefModal = false;
      this.defErrors = {};
    },
    
    async saveDef() {
      if (!this.validateDef()) return;
      
      this.savingDef = true;
      try {
        const method = this.isEditingDef ? 'PATCH' : 'POST';
        const url = this.isEditingDef ? `${BASEURL}api/valuesetdef/${this.defForm.VSetID}` : `${BASEURL}api/valuesetdef`;
        
        const res = await fetch(url, {
          method: method,
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(this.defForm),
          credentials: 'include'
        });
        
        if (res.ok) {
          this.closeDefModal();
          await this.fetchDefs();
          this.showToast(this.isEditingDef ? 'Category updated successfully' : 'Category created successfully', 'success');
        } else {
          const errorData = await res.json().catch(() => ({ message: 'Unknown error' }));
          this.defErrors = { general: errorData.message || 'Failed to save' };
        }
      } catch (err) {
        console.error(err);
        this.defErrors = { general: 'Failed to save category' };
        this.showToast('Failed to save category', 'error');
      } finally {
        this.savingDef = false;
      }
    },
    
    confirmDeleteDef(def) {
      this.deleteDefTarget = def;
      this.showDeleteDefModal = true;
    },
    
    async deleteDef() {
      if (!this.deleteDefTarget) return;
      
      this.deletingDef = true;
      try {
        const res = await fetch(`${BASEURL}api/valuesetdef/${this.deleteDefTarget.VSetID}`, {
          method: 'DELETE',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include'
        });
        
        if (res.ok) {
          this.showDeleteDefModal = false;
          if (this.selectedDef?.VSetID === this.deleteDefTarget.VSetID) {
            this.selectedDef = null;
            this.valueList = [];
          }
          await this.fetchDefs();
          this.showToast('Category deleted successfully', 'success');
        } else {
          this.showToast('Failed to delete category', 'error');
        }
      } catch (err) {
        console.error(err);
        this.showToast('Failed to delete category', 'error');
      } finally {
        this.deletingDef = false;
        this.deleteDefTarget = null;
      }
    },
    
    // ==================== VALUE METHODS ====================
    
    selectDef(def) {
      this.selectedDef = def;
      this.fetchValues();
    },
    
    async fetchValues() {
      if (!this.selectedDef) return;
      
      this.valueLoading = true;
      try {
        const params = new URLSearchParams();
        params.append('VSetID', this.selectedDef.VSetID);
        if (this.valueKeyword) params.append('param', this.valueKeyword);
        
        const res = await fetch(`${BASEURL}api/valueset?${params}`, {
          credentials: 'include'
        });
        if (!res.ok) throw new Error("HTTP error");
        const data = await res.json();
        this.valueList = data.data || [];
      } catch (err) {
        console.error(err);
        this.valueList = [];
        this.showToast('Failed to load items', 'error');
      } finally {
        this.valueLoading = false;
      }
    },
    
    async fetchDefsList() {
      try {
        const res = await fetch(`${BASEURL}api/valuesetdef?limit=1000`, {
          credentials: 'include'
        });
        if (!res.ok) throw new Error("HTTP error");
        const data = await res.json();
        this.defsList = data.data || [];
      } catch (err) {
        console.error('Failed to fetch defs list:', err);
        this.defsList = [];
      }
    },
    
    showValueForm() {
      if (!this.selectedDef) {
        this.showToast('Please select a category first', 'warning');
        return;
      }
      
      this.isEditingValue = false;
      this.valueForm = {
        VID: null,
        VSetID: this.selectedDef.VSetID,
        VOrder: 0,
        VValue: "",
        VDesc: "",
        SiteID: 1
      };
      this.valueErrors = {};
      this.showValueModal = true;
    },
    
    async editValue(id) {
      this.isEditingValue = true;
      this.valueErrors = {};
      try {
        const res = await fetch(`${BASEURL}api/valueset/${id}`, {
          credentials: 'include'
        });
        const data = await res.json();
        if (data.data) {
          this.valueForm = { ...this.valueForm, ...data.data };
          this.showValueModal = true;
        }
      } catch (err) {
        console.error(err);
        this.showToast('Failed to load item data', 'error');
      }
    },
    
    validateValue() {
      const e = {};
      if (!this.valueForm.VValue?.trim()) e.VValue = "Value is required";
      if (!this.valueForm.VSetID) e.VSetID = "Category is required";
      this.valueErrors = e;
      return Object.keys(e).length === 0;
    },
    
    closeValueModal() {
      this.showValueModal = false;
      this.valueErrors = {};
    },
    
    async saveValue() {
      if (!this.validateValue()) return;
      
      this.savingValue = true;
      try {
        const method = this.isEditingValue ? 'PATCH' : 'POST';
        const url = this.isEditingValue ? `${BASEURL}api/valueset/${this.valueForm.VID}` : `${BASEURL}api/valueset`;
        
        const res = await fetch(url, {
          method: method,
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(this.valueForm),
          credentials: 'include'
        });
        
        if (res.ok) {
          this.closeValueModal();
          await this.fetchValues();
          await this.fetchDefs(); // Refresh item counts
          this.showToast(this.isEditingValue ? 'Item updated successfully' : 'Item created successfully', 'success');
        } else {
          const errorData = await res.json().catch(() => ({ message: 'Unknown error' }));
          this.valueErrors = { general: errorData.message || 'Failed to save' };
        }
      } catch (err) {
        console.error(err);
        this.valueErrors = { general: 'Failed to save item' };
        this.showToast('Failed to save item', 'error');
      } finally {
        this.savingValue = false;
      }
    },
    
    confirmDeleteValue(value) {
      this.deleteValueTarget = value;
      this.showDeleteValueModal = true;
    },
    
    async deleteValue() {
      if (!this.deleteValueTarget) return;
      
      this.deletingValue = true;
      try {
        const res = await fetch(`${BASEURL}api/valueset/${this.deleteValueTarget.VID}`, {
          method: 'DELETE',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include'
        });
        
        if (res.ok) {
          this.showDeleteValueModal = false;
          await this.fetchValues();
          await this.fetchDefs(); // Refresh item counts
          this.showToast('Item deleted successfully', 'success');
        } else {
          this.showToast('Failed to delete item', 'error');
        }
      } catch (err) {
        console.error(err);
        this.showToast('Failed to delete item', 'error');
      } finally {
        this.deletingValue = false;
        this.deleteValueTarget = null;
      }
    },
    
    // ==================== UTILITIES ====================
    
    showToast(message, type = 'info') {
      if (this.$root && this.$root.showToast) {
        this.$root.showToast(message, type);
      } else {
        alert(message);
      }
    }
  }
}
</script>
<?= $this->endSection() ?>
