'use client';

import { useState, useEffect, useCallback } from 'react';
import { listFills, previewFill, executeFill, undoFill } from '@/services/organizer';
import { listRegimens } from '@/services/regimens';
import { OrganizerFillStatus } from '@meshitrack/shared';
import type { z } from 'zod/v4';
import type {
  OrganizerFillResponseSchema,
  OrganizerPreviewResponseSchema,
  RegimenResponseSchema,
} from '@meshitrack/shared';

type OrganizerFill = z.infer<typeof OrganizerFillResponseSchema>;
type OrganizerPreview = z.infer<typeof OrganizerPreviewResponseSchema>;
type Regimen = z.infer<typeof RegimenResponseSchema>;

const STATUS_LABELS: Record<string, string> = {
  completed: 'Completed',
  partial: 'Partial',
  reversed: 'Reversed',
};

function formatDate(dateStr: string): string {
  return new Date(dateStr).toLocaleDateString();
}

// --- Preview result display ---

function PreviewResult({
  preview,
  onConfirm,
  onCancel,
  submitting,
  allowPartial,
  onTogglePartial,
}: {
  preview: OrganizerPreview;
  onConfirm: () => void;
  onCancel: () => void;
  submitting: boolean;
  allowPartial: boolean;
  onTogglePartial: (v: boolean) => void;
}) {
  return (
    <div className="mt-card">
      <div className="flex items-center justify-between">
        <h3 className="text-base font-semibold">
          Preview: {preview.regimenName} &mdash; {preview.numberOfDays} day
          {preview.numberOfDays !== 1 ? 's' : ''}
        </h3>
        {preview.hasShortages ? (
          <span className="mt-pill mt-pill--warn">Shortages detected</span>
        ) : (
          <span className="mt-pill mt-pill--ok">Ready to fill</span>
        )}
      </div>

      <div className="space-y-2">
        {preview.items.map((item) => (
          <div
            key={item.medicineId}
            className={`rounded-lg border p-3 ${item.isShort ? 'border-yellow-300 bg-yellow-50' : 'border-gray-200'}`}
          >
            <div className="flex items-center justify-between">
              <span className="text-sm font-medium text-gray-900">{item.medicineName}</span>
              <div className="flex items-center gap-4 text-sm">
                <span className="text-gray-500">
                  Need: <strong>{item.quantityNeeded}</strong>
                </span>
                <span className="text-gray-500">
                  Available: <strong>{item.quantityAvailable}</strong>
                </span>
                {item.isShort && (
                  <span className="text-yellow-700 font-semibold">Short: {item.shortage}</span>
                )}
              </div>
            </div>
            {item.cabinetBreakdown.length > 0 && (
              <div className="mt-2 flex flex-wrap gap-1">
                {item.cabinetBreakdown.map((b, i) => (
                  <span key={i} className="rounded bg-blue-50 px-2 py-0.5 text-xs text-blue-700">
                    {b.quantityToTake} units
                    {b.expirationDate
                      ? ` (exp ${new Date(b.expirationDate).toLocaleDateString()})`
                      : ''}
                  </span>
                ))}
              </div>
            )}
          </div>
        ))}
      </div>

      {preview.hasShortages && (
        <div className="flex items-center gap-2">
          <input
            type="checkbox"
            id="allowPartial"
            checked={allowPartial}
            onChange={(e) => onTogglePartial(e.target.checked)}
            className="h-4 w-4 rounded border-gray-300"
          />
          <label htmlFor="allowPartial" className="text-sm text-gray-700">
            Allow partial fill (fill what is available)
          </label>
        </div>
      )}

      <div className="flex gap-3">
        <button
          onClick={onConfirm}
          disabled={submitting || (preview.hasShortages && !allowPartial)}
          className="mt-btn mt-btn--primary"
        >
          {submitting ? 'Filling...' : 'Confirm fill'}
        </button>
        <button onClick={onCancel} className="mt-btn mt-btn--ghost">
          Back
        </button>
      </div>
    </div>
  );
}

// --- Fill wizard ---

function FillWizard({
  householdId,
  regimens,
  onFilled,
}: {
  householdId: string;
  regimens: Regimen[];
  onFilled: () => void;
}) {
  const [regimenId, setRegimenId] = useState('');
  const [numberOfDays, setNumberOfDays] = useState(7);
  const [notes, setNotes] = useState('');
  const [allowPartial, setAllowPartial] = useState(false);
  const [preview, setPreview] = useState<OrganizerPreview | null>(null);
  const [previewing, setPreviewing] = useState(false);
  const [filling, setFilling] = useState(false);
  const [error, setError] = useState('');

  const activeRegimens = regimens.filter((r) => r.isActive);

  async function handlePreview(e: React.FormEvent) {
    e.preventDefault();
    setError('');
    setPreviewing(true);
    try {
      const result = await previewFill(householdId, { regimenId, numberOfDays });
      setPreview(result);
      setAllowPartial(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to generate preview');
    } finally {
      setPreviewing(false);
    }
  }

  async function handleFill() {
    setError('');
    setFilling(true);
    try {
      await executeFill(householdId, {
        regimenId,
        numberOfDays,
        allowPartial,
        notes: notes || undefined,
      });
      setPreview(null);
      setRegimenId('');
      setNumberOfDays(7);
      setNotes('');
      setAllowPartial(false);
      onFilled();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Fill failed');
      setPreview(null);
    } finally {
      setFilling(false);
    }
  }

  if (preview) {
    return (
      <>
        {error && (
          <div className="mb-4 rounded-lg bg-red-50 border border-red-200 p-3 text-sm text-red-700">
            {error}
          </div>
        )}
        <PreviewResult
          preview={preview}
          onConfirm={handleFill}
          onCancel={() => setPreview(null)}
          submitting={filling}
          allowPartial={allowPartial}
          onTogglePartial={setAllowPartial}
        />
      </>
    );
  }

  return (
    <div className="mt-card">
      <h2 className="text-lg font-semibold mb-4">Fill Pill Organizer</h2>
      {error && <div className="mt-alert mt-alert--danger mb-4">{error}</div>}
      {activeRegimens.length === 0 ? (
        <p className="text-sm text-gray-500">
          No active regimens found. Create and activate a regimen before filling.
        </p>
      ) : (
        <form onSubmit={handlePreview} className="space-y-4">
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
            <div>
              <label className="mt-field-label">Regimen</label>
              <select
                required
                value={regimenId}
                onChange={(e) => setRegimenId(e.target.value)}
                className="mt-field"
              >
                <option value="">Select regimen...</option>
                {activeRegimens.map((r) => (
                  <option key={r._id} value={r._id}>
                    {r.name} ({r.medications.length} medication
                    {r.medications.length !== 1 ? 's' : ''})
                  </option>
                ))}
              </select>
            </div>
            <div>
              <label className="mt-field-label">Number of days</label>
              <input
                type="number"
                required
                min={1}
                max={90}
                value={numberOfDays}
                onChange={(e) => setNumberOfDays(Number(e.target.value))}
                className="mt-field"
              />
            </div>
            <div className="md:col-span-2">
              <label className="mt-field-label">Notes (optional)</label>
              <input
                type="text"
                maxLength={1000}
                value={notes}
                onChange={(e) => setNotes(e.target.value)}
                placeholder="Any notes for this fill"
                className="mt-field"
              />
            </div>
          </div>
          <button type="submit" disabled={previewing} className="mt-btn mt-btn--primary">
            {previewing ? 'Calculating...' : 'Preview fill'}
          </button>
        </form>
      )}
    </div>
  );
}

// --- Fill history list ---

function FillHistory({ householdId, refreshKey }: { householdId: string; refreshKey: number }) {
  const [fills, setFills] = useState<OrganizerFill[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [filterStatus, setFilterStatus] = useState('');

  const fetchFills = useCallback(async () => {
    setLoading(true);
    try {
      const result = await listFills(householdId, {
        status: filterStatus || undefined,
        limit: 50,
      });
      setFills(result.data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load fill history');
    } finally {
      setLoading(false);
    }
  }, [householdId, filterStatus]);

  useEffect(() => {
    fetchFills();
  }, [fetchFills, refreshKey]);

  async function handleUndo(fillId: string) {
    if (!confirm('Reverse this fill? Cabinet quantities will be restored.')) return;
    try {
      const updated = await undoFill(householdId, fillId);
      setFills((prev) => prev.map((f) => (f._id === updated._id ? updated : f)));
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to undo fill');
    }
  }

  return (
    <div className="mt-card">
      <div className="flex items-center justify-between mb-4">
        <h2 className="text-lg font-semibold">Fill History</h2>
        <select
          value={filterStatus}
          onChange={(e) => setFilterStatus(e.target.value)}
          className="mt-field"
          style={{ width: 'auto' }}
        >
          <option value="">All statuses</option>
          {Object.values(OrganizerFillStatus).map((s) => (
            <option key={s} value={s}>
              {STATUS_LABELS[s] ?? s}
            </option>
          ))}
        </select>
      </div>

      {error && (
        <div className="mt-alert mt-alert--danger mb-4">
          {error}
          <button onClick={() => setError('')} className="ml-2 underline">
            Dismiss
          </button>
        </div>
      )}

      {loading ? (
        <div className="space-y-3">
          {Array.from({ length: 3 }).map((_, i) => (
            <div key={i} className="animate-pulse h-16 rounded-lg bg-gray-200" />
          ))}
        </div>
      ) : fills.length === 0 ? (
        <p className="text-sm text-center text-gray-500 py-4">No fills recorded yet.</p>
      ) : (
        <div className="space-y-3">
          {fills.map((fill) => (
            <div key={fill._id} className="rounded-lg border p-4">
              <div className="flex items-start justify-between gap-4">
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 mb-1">
                    <span className="font-medium text-gray-900">{fill.regimenName}</span>
                    <span
                      className={`mt-pill ${fill.status === 'completed' ? 'mt-pill--ok' : fill.status === 'partial' ? 'mt-pill--warn' : 'mt-pill--ghost'}`}
                    >
                      {STATUS_LABELS[fill.status] ?? fill.status}
                    </span>
                  </div>
                  <p className="text-sm text-gray-500">
                    {fill.numberOfDays} day{fill.numberOfDays !== 1 ? 's' : ''} &bull;{' '}
                    {fill.items.length} medicine{fill.items.length !== 1 ? 's' : ''} &bull;{' '}
                    {formatDate(fill.fillDate)}
                  </p>
                  {fill.notes && <p className="text-xs text-gray-400 mt-1">{fill.notes}</p>}
                  <div className="flex flex-wrap gap-1 mt-2">
                    {fill.items.map((item, i) => (
                      <span
                        key={i}
                        className={`mt-pill ${item.wasShort ? 'mt-pill--warn' : 'mt-pill--info'}`}
                      >
                        {item.medicineName}: {item.quantityTaken}/{item.quantityNeeded}
                        {item.wasShort ? ' (short)' : ''}
                      </span>
                    ))}
                  </div>
                </div>
                {fill.status !== OrganizerFillStatus.REVERSED && (
                  <button
                    onClick={() => handleUndo(fill._id)}
                    className="mt-btn mt-btn--danger-ghost"
                  >
                    Undo
                  </button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// --- Main component ---

export function OrganizerTab({ householdId }: { householdId: string }) {
  const [regimens, setRegimens] = useState<Regimen[]>([]);
  const [regimensLoading, setRegimensLoading] = useState(true);
  const [fillRefreshKey, setFillRefreshKey] = useState(0);

  useEffect(() => {
    listRegimens(householdId, { limit: 100 })
      .then((r) => setRegimens(r.data))
      .catch(() => {})
      .finally(() => setRegimensLoading(false));
  }, [householdId]);

  function handleFilled() {
    setFillRefreshKey((k) => k + 1);
  }

  return (
    <div className="space-y-6">
      {regimensLoading ? (
        <div className="animate-pulse rounded-xl border bg-white p-6 h-40" />
      ) : (
        <FillWizard householdId={householdId} regimens={regimens} onFilled={handleFilled} />
      )}
      <FillHistory householdId={householdId} refreshKey={fillRefreshKey} />
    </div>
  );
}
