<script>
  import { onMount } from 'svelte';
  import { 
    Search, 
    Calendar, 
    User, 
    FileText, 
    ChevronLeft, 
    ChevronRight,
    AlertTriangle,
    TrendingUp,
    TrendingDown,
    Minus,
    Printer,
    Download,
    History
  } from 'lucide-svelte';
  import { fetchResultsByPatient } from '$lib/api/results.js';
  import { fetchPatients } from '$lib/api/patients.js';
  import { error as toastError, success as toastSuccess } from '$lib/utils/toast.js';

  // Search state
  let patientId = $state('');
  let patientName = $state('');
  let startDate = $state('');
  let endDate = $state('');

  // Results state
  let loading = $state(false);
  let results = $state([]);
  let patientInfo = $state(null);
  let currentPage = $state(1);
  let perPage = $state(20);
  let totalItems = $state(0);
  
  // Grouped results by test
  let groupedResults = $state({});

  async function handleSearch() {
    if (!patientId.trim() && !patientName.trim()) {
      toastError('Please enter Patient ID or Name');
      return;
    }

    loading = true;
    currentPage = 1;
    results = [];
    patientInfo = null;
    groupedResults = {};

    try {
      // First, search for patient to get ID
      let targetPatientId = patientId.trim();
      
      if (!targetPatientId && patientName.trim()) {
        // Search by name first
        const patientResponse = await fetchPatients({ Name: patientName.trim(), perPage: 1 });
        if (patientResponse.data && patientResponse.data.length > 0) {
          targetPatientId = patientResponse.data[0].PatientID;
          patientInfo = patientResponse.data[0];
        } else {
          toastError('Patient not found');
          loading = false;
          return;
        }
      } else if (targetPatientId) {
        // Get patient details
        const patientResponse = await fetchPatients({ PatientID: targetPatientId, perPage: 1 });
        if (patientResponse.data && patientResponse.data.length > 0) {
          patientInfo = patientResponse.data[0];
        }
      }

      if (!targetPatientId) {
        toastError('Patient not found');
        loading = false;
        return;
      }

      // Now fetch results
      const params = {
        patient_id: targetPatientId,
        page: currentPage,
        per_page: perPage
      };
      
      if (startDate) params.start_date = startDate;
      if (endDate) params.end_date = endDate;

      const response = await fetchResultsByPatient(targetPatientId, currentPage, perPage);
      
      if (response.status === 'success') {
        results = response.data || [];
        totalItems = response.total || results.length;
        groupResultsByTest();
      } else {
        results = [];
        totalItems = 0;
      }
    } catch (err) {
      toastError(err.message || 'Failed to load results');
      results = [];
    } finally {
      loading = false;
    }
  }

  function groupResultsByTest() {
    const grouped = {};
    
    results.forEach(result => {
      const testCode = result.TestSiteCode || result.TestSiteName;
      if (!grouped[testCode]) {
        grouped[testCode] = {
          testCode: result.TestSiteCode,
          testName: result.TestSiteName,
          unit: result.Unit1,
          refLow: result.Low,
          refHigh: result.High,
          results: []
        };
      }
      grouped[testCode].results.push({
        resultId: result.ResultID,
        value: result.Result,
        flag: result.AbnormalFlag,
        orderId: result.OrderID,
        orderDate: result.OrderDate,
        enteredBy: result.EnteredBy,
        enteredDateTime: result.EnteredDateTime,
        refNumID: result.RefNumID
      });
    });
    
    // Sort results within each group by date (newest first)
    Object.keys(grouped).forEach(key => {
      grouped[key].results.sort((a, b) => {
        return new Date(b.enteredDateTime || 0) - new Date(a.enteredDateTime || 0);
      });
    });
    
    groupedResults = grouped;
  }

  function handleClear() {
    patientId = '';
    patientName = '';
    startDate = '';
    endDate = '';
    results = [];
    patientInfo = null;
    groupedResults = {};
    totalItems = 0;
  }

  function handlePageChange(newPage) {
    currentPage = newPage;
    handleSearch();
  }

  function getTrendIndicator(current, previous) {
    if (!current || !previous) return null;
    const currVal = parseFloat(current);
    const prevVal = parseFloat(previous);
    if (isNaN(currVal) || isNaN(prevVal)) return null;
    
    if (currVal > prevVal) return { icon: TrendingUp, color: 'text-success' };
    if (currVal < prevVal) return { icon: TrendingDown, color: 'text-error' };
    return { icon: Minus, color: 'text-base-content/40' };
  }

  function getFlagBadge(flag) {
    if (flag === 'H') return { color: 'badge-error', label: 'High' };
    if (flag === 'L') return { color: 'badge-warning', label: 'Low' };
    return { color: 'badge-success', label: 'Normal' };
  }

  function formatDate(dateString) {
    if (!dateString) return '-';
    const date = new Date(dateString);
    return date.toLocaleDateString('en-US', { 
      month: 'short', 
      day: 'numeric',
      year: 'numeric'
    });
  }

  function formatDateTime(dateString) {
    if (!dateString) return '-';
    const date = new Date(dateString);
    return date.toLocaleString('en-US', { 
      month: 'short', 
      day: 'numeric',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });
  }

  function handlePrint() {
    window.print();
  }

  const totalPages = $derived(Math.ceil(totalItems / perPage));
  const hasResults = $derived(Object.keys(groupedResults).length > 0);
</script>

<div class="p-4 space-y-4">
  <!-- Header -->
  <div class="flex items-center justify-between print:hidden">
    <h1 class="text-2xl font-bold text-primary flex items-center gap-2">
      <History class="w-6 h-6" />
      Patient Results History
    </h1>
    {#if hasResults}
      <div class="flex gap-2">
        <button class="btn btn-sm btn-ghost" onclick={handlePrint}>
          <Printer class="w-4 h-4 mr-1" />
          Print
        </button>
      </div>
    {/if}
  </div>

  <!-- Search Panel -->
  <div class="card bg-base-100 shadow compact-card print:hidden">
    <div class="card-body p-3">
      <div class="flex flex-wrap gap-3 items-end">
        <div class="form-control w-40">
          <span class="label-text text-xs mb-1">Patient ID</span>
          <label class="input input-sm input-bordered flex items-center gap-2">
            <User class="w-3 h-3 text-gray-400" />
            <input 
              type="text" 
              class="grow bg-transparent outline-none text-sm"
              placeholder="Enter ID..."
              bind:value={patientId}
            />
          </label>
        </div>

        <div class="form-control w-48">
          <span class="label-text text-xs mb-1">Patient Name</span>
          <label class="input input-sm input-bordered flex items-center gap-2">
            <User class="w-3 h-3 text-gray-400" />
            <input 
              type="text" 
              class="grow bg-transparent outline-none text-sm"
              placeholder="Search by name..."
              bind:value={patientName}
            />
          </label>
        </div>

        <div class="form-control w-36">
          <span class="label-text text-xs mb-1">Start Date</span>
          <label class="input input-sm input-bordered flex items-center gap-2">
            <Calendar class="w-3 h-3 text-gray-400" />
            <input 
              type="date" 
              class="grow bg-transparent outline-none text-sm"
              bind:value={startDate}
            />
          </label>
        </div>

        <div class="form-control w-36">
          <span class="label-text text-xs mb-1">End Date</span>
          <label class="input input-sm input-bordered flex items-center gap-2">
            <Calendar class="w-3 h-3 text-gray-400" />
            <input 
              type="date" 
              class="grow bg-transparent outline-none text-sm"
              bind:value={endDate}
            />
          </label>
        </div>

        <div class="flex gap-2 ml-auto">
          <button class="btn btn-sm btn-primary" onclick={handleSearch} disabled={loading}>
            {#if loading}
              <span class="loading loading-spinner loading-xs"></span>
            {:else}
              <Search class="w-4 h-4" />
            {/if}
            Search
          </button>
          <button class="btn btn-sm btn-ghost" onclick={handleClear}>
            Clear
          </button>
        </div>
      </div>
    </div>
  </div>

  <!-- Patient Info -->
  {#if patientInfo}
    <div class="card bg-primary/5 border border-primary/20">
      <div class="card-body p-4">
        <div class="flex items-center gap-4">
          <div class="w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center">
            <User class="w-6 h-6 text-primary" />
          </div>
          <div>
            <h2 class="text-lg font-bold">{patientInfo.PatientName || patientInfo.Name || 'Unknown'}</h2>
            <div class="text-sm text-base-content/60 flex gap-4">
              <span>ID: {patientInfo.PatientID || patientInfo.InternalPID}</span>
              {#if patientInfo.DateOfBirth}
                <span>DOB: {formatDate(patientInfo.DateOfBirth)}</span>
              {/if}
              {#if patientInfo.Gender}
                <span>Gender: {patientInfo.Gender}</span>
              {/if}
            </div>
          </div>
          <div class="ml-auto text-right">
            <div class="text-2xl font-bold text-primary">{Object.keys(groupedResults).length}</div>
            <div class="text-sm text-base-content/60">Tests</div>
          </div>
        </div>
      </div>
    </div>
  {/if}

  <!-- Results Table -->
  {#if hasResults}
    <div class="card bg-base-100 shadow compact-card">
      <div class="card-body p-0">
        <div class="overflow-x-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-20">Test Code</th>
                <th class="text-xs font-semibold w-40">Test Name</th>
                <th class="text-xs font-semibold w-20">Unit</th>
                <th class="text-xs font-semibold w-28">Reference</th>
                <th class="text-xs font-semibold w-24">Latest</th>
                <th class="text-xs font-semibold w-12 text-center">Flag</th>
                <th class="text-xs font-semibold w-20 text-center">Trend</th>
                <th class="text-xs font-semibold w-24">Previous</th>
                <th class="text-xs font-semibold w-28">Order Date</th>
              </tr>
            </thead>
            <tbody>
              {#each Object.entries(groupedResults) as [testCode, testData]}
                {@const latest = testData.results[0]}
                {@const previous = testData.results[1]}
                {@const flag = getFlagBadge(latest.flag)}
                {@const trend = getTrendIndicator(latest.value, previous?.value)}
                <tr class="hover:bg-base-200/30">
                  <td class="text-xs font-mono">{testData.testCode}</td>
                  <td class="text-xs font-medium">{testData.testName}</td>
                  <td class="text-xs text-base-content/60">{testData.unit || '-'}</td>
                  <td class="text-xs text-base-content/60">
                    {#if testData.refLow !== null && testData.refHigh !== null}
                      {testData.refLow} - {testData.refHigh}
                    {:else}
                      -
                    {/if}
                  </td>
                  <td class="text-sm font-mono font-semibold">
                    {latest.value || '-'}
                  </td>
                  <td class="text-center">
                    <span class="badge {flag.color} badge-sm">{flag.label}</span>
                  </td>
                  <td class="text-center">
                    {#if trend}
                      <svelte:component this={trend.icon} class="w-4 h-4 {trend.color} inline" />
                    {:else}
                      <span class="text-base-content/30">-</span>
                    {/if}
                  </td>
                  <td class="text-xs text-base-content/60 font-mono">
                    {previous?.value || '-'}
                  </td>
                  <td class="text-xs text-base-content/60">
                    {formatDateTime(latest.enteredDateTime)}
                  </td>
                </tr>
              {/each}
            </tbody>
          </table>
        </div>

        <!-- Pagination -->
        {#if totalPages > 1}
          <div class="flex justify-center p-3 border-t border-base-200 print:hidden">
            <div class="join">
              <button 
                class="join-item btn btn-sm" 
                disabled={currentPage === 1}
                onclick={() => handlePageChange(currentPage - 1)}
              >
                <ChevronLeft class="w-4 h-4" />
              </button>
              <span class="join-item btn btn-sm btn-ghost">
                Page {currentPage} of {totalPages}
              </span>
              <button 
                class="join-item btn btn-sm" 
                disabled={currentPage >= totalPages}
                onclick={() => handlePageChange(currentPage + 1)}
              >
                <ChevronRight class="w-4 h-4" />
              </button>
            </div>
          </div>
        {/if}
      </div>
    </div>

    <!-- Detailed History per Test -->
    <div class="space-y-4 print:break-before-page">
      <h2 class="text-xl font-bold print:mt-8">Detailed History</h2>
      
      {#each Object.entries(groupedResults) as [testCode, testData]}
        <div class="card bg-base-100 shadow compact-card print:border print:border-gray-300">
          <div class="card-body p-3">
            <div class="flex items-center justify-between mb-3">
              <div class="flex items-center gap-3">
                <span class="font-mono text-sm bg-base-200 px-2 py-1 rounded">{testData.testCode}</span>
                <span class="font-semibold">{testData.testName}</span>
                {#if testData.unit}
                  <span class="text-sm text-base-content/60">({testData.unit})</span>
                {/if}
              </div>
              <div class="text-sm text-base-content/60">
                {testData.results.length} result(s)
              </div>
            </div>

            <div class="overflow-x-auto">
              <table class="table table-sm">
                <thead>
                  <tr class="bg-base-200/50">
                    <th class="text-xs">Result</th>
                    <th class="text-xs">Flag</th>
                    <th class="text-xs">Order ID</th>
                    <th class="text-xs">Date/Time</th>
                    <th class="text-xs">Entered By</th>
                  </tr>
                </thead>
                <tbody>
                  {#each testData.results as result}
                    {@const flag = getFlagBadge(result.flag)}
                    <tr class="hover:bg-base-200/20">
                      <td class="text-sm font-mono">{result.value || '-'}</td>
                      <td>
                        <span class="badge {flag.color} badge-sm">{flag.label}</span>
                      </td>
                      <td class="text-xs font-mono">{result.orderId}</td>
                      <td class="text-xs">{formatDateTime(result.enteredDateTime)}</td>
                      <td class="text-xs text-base-content/60">{result.enteredBy || '-'}</td>
                    </tr>
                  {/each}
                </tbody>
              </table>
            </div>
          </div>
        </div>
      {/each}
    </div>
  {:else if !loading && patientInfo}
    <div class="card bg-base-100 shadow compact-card">
      <div class="card-body p-8 text-center">
        <FileText class="w-12 h-12 mx-auto mb-2 opacity-30" />
        <p class="text-base-content/50">No results found for this patient</p>
      </div>
    </div>
  {/if}
</div>

<style>
  @media print {
    .print\:hidden {
      display: none !important;
    }
    .print\:border {
      border: 1px solid #ccc !important;
    }
    .print\:break-before-page {
      break-before: page;
    }
    .print\:mt-8 {
      margin-top: 2rem !important;
    }
  }
</style>
