<script>
  import { FlaskConical, AlertTriangle, CheckCircle2, X, Save, User, FileText } from 'lucide-svelte';
  import { updateResult } from '$lib/api/results.js';
  import { error as toastError, success as toastSuccess } from '$lib/utils/toast.js';
  import Modal from '$lib/components/Modal.svelte';

  let { 
    order = $bindable(),
    open = $bindable(false),
    onSaved
  } = $props();

  // Form state - array of result entries
  let results = $state([]);
  let formLoading = $state(false);
  let saveProgress = $state({ current: 0, total: 0 });

  // Initialize results when order changes
  $effect(() => {
    if (order && open) {
      // Map tests to editable result entries
      results = (order.Tests || []).map(test => ({
        ResultID: test.ResultID,
        TestSiteID: test.TestSiteID,
        TestSiteCode: test.TestSiteCode,
        TestSiteName: test.TestSiteName,
        Result: test.Result || '',
        SampleType: test.SampleType || '',
        WorkstationID: test.WorkstationID || '',
        EquipmentID: test.EquipmentID || '',
        Unit1: test.Unit1,
        Low: test.Low,
        High: test.High,
        LowSign: test.LowSign,
        HighSign: test.HighSign,
        RefDisplay: test.RefDisplay,
        RefNumID: test.RefNumID,
        flag: calculateFlag(test.Result, test.Low, test.High),
        saved: false,
        error: null
      }));
      saveProgress = { current: 0, total: 0 };
    }
  });

  function calculateFlag(value, low, high) {
    if (!value || value === '') return null;
    
    const numValue = parseFloat(value);
    if (isNaN(numValue)) return null;
    
    if (low !== null && numValue < low) return 'L';
    if (high !== null && numValue > high) return 'H';
    return null;
  }

  function updateResultFlag(index) {
    const entry = results[index];
    results[index].flag = calculateFlag(entry.Result, entry.Low, entry.High);
  }

  function getFlagColor(flag) {
    if (flag === 'H') return 'text-error';
    if (flag === 'L') return 'text-warning';
    return 'text-success';
  }

  function getFlagBg(flag) {
    if (flag === 'H') return 'bg-error/10';
    if (flag === 'L') return 'bg-warning/10';
    return 'bg-success/10';
  }

  function getInputBg(flag) {
    if (flag === 'H') return 'bg-error/5 border-error/30';
    if (flag === 'L') return 'bg-warning/5 border-warning/30';
    return '';
  }

  async function handleSaveAll() {
    // Filter to only entries with values that haven't been saved yet
    const entriesToSave = results.filter(r => r.Result && r.Result.trim() !== '' && !r.saved);
    
    if (entriesToSave.length === 0) {
      toastError('No results to save');
      return;
    }

    formLoading = true;
    saveProgress = { current: 0, total: entriesToSave.length };

    try {
      // Save each result sequentially
      for (let i = 0; i < entriesToSave.length; i++) {
        const entry = entriesToSave[i];
        saveProgress.current = i + 1;

        const data = {
          Result: entry.Result,
          SampleType: entry.SampleType || null,
          WorkstationID: entry.WorkstationID ? parseInt(entry.WorkstationID) : null,
          EquipmentID: entry.EquipmentID ? parseInt(entry.EquipmentID) : null,
          RefNumID: entry.RefNumID || null
        };

        const response = await updateResult(entry.ResultID, data);
        
        if (response.status === 'success') {
          // Mark as saved
          const resultIndex = results.findIndex(r => r.ResultID === entry.ResultID);
          if (resultIndex !== -1) {
            results[resultIndex].saved = true;
            results[resultIndex].error = null;
          }
        } else {
          // Mark with error
          const resultIndex = results.findIndex(r => r.ResultID === entry.ResultID);
          if (resultIndex !== -1) {
            results[resultIndex].error = response.message || 'Failed to save';
          }
        }
      }

      // Check if all were saved successfully
      const failedCount = results.filter(r => r.error).length;
      if (failedCount === 0) {
        toastSuccess(`Saved ${entriesToSave.length} result(s) successfully`);
        onSaved?.();
      } else {
        toastError(`${failedCount} result(s) failed to save`);
      }
    } catch (err) {
      toastError(err.message || 'Failed to save results');
    } finally {
      formLoading = false;
      saveProgress = { current: 0, total: 0 };
    }
  }

  function handleClose() {
    open = false;
  }

  function handleKeyDown(event, index) {
    // Navigate with Enter/Arrow keys
    if (event.key === 'Enter') {
      event.preventDefault();
      const nextIndex = index + 1;
      if (nextIndex < results.length) {
        const nextInput = document.getElementById(`result-input-${nextIndex}`);
        nextInput?.focus();
        nextInput?.select();
      }
    }
  }

  const pendingCount = $derived(results.filter(r => !r.Result || r.Result === '').length);
  const savedCount = $derived(results.filter(r => r.saved).length);
</script>

<Modal bind:open={open} title="Enter Results - Order {order?.OrderID}" size="xl">
  {#snippet children()}
    <div class="space-y-4">
      <!-- Order Info Header -->
      <div class="bg-base-200/50 rounded-lg p-3">
        <div class="flex items-center justify-between">
          <div class="flex items-center gap-4">
            <div class="flex items-center gap-2">
              <User class="w-4 h-4 text-primary" />
              <span class="text-sm font-medium">{order?.PatientName || 'Unknown'}</span>
              <span class="text-xs text-base-content/50">(ID: {order?.InternalPID})</span>
            </div>
            <div class="flex items-center gap-2">
              <FileText class="w-4 h-4 text-primary" />
              <span class="text-xs text-base-content/70">{order?.Tests?.length || 0} tests</span>
            </div>
          </div>
          <div class="flex items-center gap-2 text-xs">
            {#if pendingCount > 0}
              <span class="badge badge-warning badge-sm">{pendingCount} pending</span>
            {/if}
            {#if savedCount > 0}
              <span class="badge badge-success badge-sm">{savedCount} saved</span>
            {/if}
          </div>
        </div>
      </div>

      <!-- Results Table -->
      <div class="overflow-x-auto max-h-[400px] overflow-y-auto">
        <table class="table table-sm">
          <thead class="sticky top-0 bg-base-100 z-10">
            <tr class="bg-base-200">
              <th class="text-xs font-semibold w-16">Code</th>
              <th class="text-xs font-semibold">Test Name</th>
              <th class="text-xs font-semibold w-32">Result</th>
              <th class="text-xs font-semibold w-16">Flag</th>
              <th class="text-xs font-semibold w-24">Reference</th>
              <th class="text-xs font-semibold w-20">Unit</th>
            </tr>
          </thead>
          <tbody>
            {#each results as result, index (result.ResultID)}
              <tr class="hover:bg-base-200/30 {result.saved ? 'opacity-60' : ''}">
                <td class="text-xs font-mono">{result.TestSiteCode}</td>
                <td class="text-xs">
                  {result.TestSiteName}
                  {#if result.error}
                    <div class="text-error text-xs">{result.error}</div>
                  {/if}
                </td>
                <td class="p-1">
                  <label class="input input-sm input-bordered flex items-center gap-1 w-full {getInputBg(result.flag)}">
                    {#if result.flag === 'H'}
                      <AlertTriangle class="w-3 h-3 text-error flex-shrink-0" />
                    {:else if result.flag === 'L'}
                      <AlertTriangle class="w-3 h-3 text-warning flex-shrink-0" />
                    {:else if result.Result}
                      <CheckCircle2 class="w-3 h-3 text-success flex-shrink-0" />
                    {/if}
                    <input 
                      id="result-input-{index}"
                      type="text" 
                      class="grow bg-transparent outline-none text-sm font-mono"
                      placeholder="..."
                      bind:value={result.Result}
                      oninput={() => updateResultFlag(index)}
                      onkeydown={(e) => handleKeyDown(e, index)}
                      disabled={result.saved || formLoading}
                    />
                    {#if result.Unit1}
                      <span class="text-xs text-base-content/50 flex-shrink-0">{result.Unit1}</span>
                    {/if}
                  </label>
                </td>
                <td class="text-xs text-center">
                  {#if result.flag}
                    <span class="badge {result.flag === 'H' ? 'badge-error' : 'badge-warning'} badge-sm">
                      {result.flag}
                    </span>
                  {:else}
                    <span class="text-base-content/30">-</span>
                  {/if}
                </td>
                <td class="text-xs text-base-content/60">{result.RefDisplay || '-'}</td>
                <td class="text-xs">{result.Unit1 || '-'}</td>
              </tr>
            {/each}
          </tbody>
        </table>
      </div>

      <!-- Legend -->
      <div class="flex gap-4 text-xs text-base-content/60 pt-2 border-t">
        <div class="flex items-center gap-1">
          <span class="badge badge-error badge-sm">H</span>
          <span>High</span>
        </div>
        <div class="flex items-center gap-1">
          <span class="badge badge-warning badge-sm">L</span>
          <span>Low</span>
        </div>
        <div class="flex items-center gap-1">
          <CheckCircle2 class="w-3 h-3 text-success" />
          <span>Normal</span>
        </div>
        <div class="flex-1 text-right">
          <span class="text-base-content/40">Press Enter to move to next field</span>
        </div>
      </div>

      <!-- Progress -->
      {#if formLoading && saveProgress.total > 0}
        <div class="flex items-center gap-2 text-sm">
          <span class="loading loading-spinner loading-xs"></span>
          <span>Saving {saveProgress.current} of {saveProgress.total}...</span>
        </div>
      {/if}
    </div>
  {/snippet}

  {#snippet footer()}
    <button class="btn btn-ghost btn-sm" onclick={handleClose} disabled={formLoading}>
      <X class="w-4 h-4" />
      Close
    </button>
    <button 
      class="btn btn-primary btn-sm" 
      onclick={handleSaveAll}
      disabled={formLoading || pendingCount === results.length}
    >
      {#if formLoading}
        <span class="loading loading-spinner loading-xs"></span>
        Saving...
      {:else}
        <Save class="w-4 h-4" />
        Save All Results
      {/if}
    </button>
  {/snippet}
</Modal>
