'use client';

import { useState, useRef } from 'react';
import { Upload, FileText, CheckCircle, XCircle, Edit2, AlertTriangle, ChevronRight, Loader2, Check, X } from 'lucide-react';
import { useLanguage } from '@client/contexts/LanguageContext';

type TFn = (key: string, fallback?: string, vars?: Record<string, string | number>) => string;

type UploadStep = 'upload' | 'review' | 'saving' | 'done';

interface ParsedItem {
  id: string;
  name: string;
  price: number;
  category: string;
  description: string;
  status: 'approved' | 'rejected' | 'pending';
  error?: string;
}

interface SaveResult {
  item: ParsedItem;
  ok: boolean;
  error?: string;
}

function parseCsvRow(row: string): string[] {
  const result: string[] = [];
  let current = '';
  let inQuotes = false;
  for (let i = 0; i < row.length; i++) {
    const ch = row[i];
    if (ch === '"') { inQuotes = !inQuotes; }
    else if (ch === ',' && !inQuotes) { result.push(current.trim()); current = ''; }
    else { current += ch; }
  }
  result.push(current.trim());
  return result;
}

function parseFile(text: string, filename: string, t: TFn): ParsedItem[] {
  const ext = filename.split('.').pop()?.toLowerCase();
  if (ext === 'json') {
    try {
      const arr = JSON.parse(text);
      if (!Array.isArray(arr)) throw new Error('JSON must be an array');
      return arr.map((row: Record<string, unknown>, i: number) => ({
        id: `row-${i}`,
        name: String(row.name || row.item_name || '').trim(),
        price: parseFloat(String(row.price || '0')) || 0,
        category: String(row.category || t('menuManagement.uncategorised', 'Uncategorised')).trim(),
        description: String(row.description || '').trim(),
        status: 'pending' as const,
      }));
    } catch (e) {
      throw new Error(`Invalid JSON: ${e instanceof Error ? e.message : 'parse error'}`);
    }
  }

  const lines = text.split(/\r?\n/).filter(l => l.trim());
  if (lines.length < 2) throw new Error('CSV must have a header row and at least one data row');
  const headers = parseCsvRow(lines[0]).map(h => h.toLowerCase().replace(/\s+/g, '_'));

  const nameIdx = headers.findIndex(h => ['name', 'item_name', 'item', 'title'].includes(h));
  const priceIdx = headers.findIndex(h => ['price', 'cost', 'amount'].includes(h));
  const catIdx = headers.findIndex(h => ['category', 'cat', 'section', 'type'].includes(h));
  const descIdx = headers.findIndex(h => ['description', 'desc', 'details'].includes(h));

  if (nameIdx < 0) throw new Error('CSV must have a "name" or "item_name" column');

  return lines.slice(1).map((line, i) => {
    const cols = parseCsvRow(line);
    const name = (cols[nameIdx] || '').trim();
    const priceStr = priceIdx >= 0 ? cols[priceIdx] : '0';
    const price = parseFloat(priceStr.replace(/[^0-9.]/g, '')) || 0;
    return {
      id: `row-${i}`,
      name,
      price,
      category: catIdx >= 0 ? (cols[catIdx] || t('menuManagement.uncategorised', 'Uncategorised')).trim() : t('menuManagement.uncategorised', 'Uncategorised'),
      description: descIdx >= 0 ? (cols[descIdx] || '').trim() : '',
      status: 'pending' as const,
      error: !name ? t('menuManagement.missingItemName', 'Missing item name') : undefined,
    };
  }).filter(r => r.name || r.error);
}

export default function BulkUploadTab() {
  const { t } = useLanguage();
  const [step, setStep] = useState<UploadStep>('upload');
  const [items, setItems] = useState<ParsedItem[]>([]);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editForm, setEditForm] = useState<Partial<ParsedItem>>({});
  const [dragging, setDragging] = useState(false);
  const [parseError, setParseError] = useState<string | null>(null);
  const [saveResults, setSaveResults] = useState<SaveResult[]>([]);
  const [savingProgress, setSavingProgress] = useState(0);
  const fileRef = useRef<HTMLInputElement>(null);

  const handleFile = (file: File) => {
    setParseError(null);
    const reader = new FileReader();
    reader.onload = e => {
      const text = e.target?.result as string;
      try {
        const parsed = parseFile(text, file.name, t);
        setItems(parsed);
        setStep('review');
      } catch (err) {
        setParseError(err instanceof Error ? err.message : 'Failed to parse file');
      }
    };
    reader.readAsText(file);
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragging(false);
    const file = e.dataTransfer.files[0];
    if (file) handleFile(file);
  };

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) handleFile(file);
  };

  const updateItem = (id: string, updates: Partial<ParsedItem>) => {
    setItems(prev => prev.map(i => i.id === id ? { ...i, ...updates } : i));
  };

  const approveAll = () => setItems(prev => prev.map(i => i.error ? i : { ...i, status: 'approved' as const }));
  const rejectLow = () => setItems(prev => prev.map(i => i.error ? { ...i, status: 'rejected' as const } : i));

  const handleSave = async () => {
    const approved = items.filter(i => i.status === 'approved');
    if (approved.length === 0) return;
    setStep('saving');
    setSavingProgress(0);

    const results: SaveResult[] = [];
    for (let i = 0; i < approved.length; i++) {
      const item = approved[i];
      try {
        const res = await fetch('/api/menu/items', {
          method: 'POST',
          credentials: 'include',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ name: item.name, price: item.price, category: item.category, description: item.description, is_available: true }),
        });
        if (res.ok) {
          results.push({ item, ok: true });
        } else {
          const json = await res.json().catch(() => ({})) as { error?: string };
          results.push({ item, ok: false, error: json.error ?? `HTTP ${res.status}` });
        }
      } catch (e) {
        results.push({ item, ok: false, error: e instanceof Error ? e.message : 'Network error' });
      }
      setSavingProgress(Math.round(((i + 1) / approved.length) * 100));
    }
    setSaveResults(results);
    setStep('done');
  };

  const approvedCount = items.filter(i => i.status === 'approved').length;
  const rejectedCount = items.filter(i => i.status === 'rejected').length;
  const pendingCount = items.filter(i => i.status === 'pending').length;

  const reset = () => { setStep('upload'); setItems([]); setParseError(null); setSaveResults([]); setSavingProgress(0); setEditingId(null); };

  return (
    <>
      {/* Step indicator */}
      <div className="flex items-center gap-2 mb-6">
        {(['upload', 'review', 'saving', 'done'] as UploadStep[]).map((s, idx) => {
          const labels = [
            t('menuManagement.uploadFile', 'Upload File'),
            t('menuManagement.reviewItems', 'Review Items'),
            t('menuManagement.saving', 'Saving'),
            t('menuManagement.complete', 'Complete')
          ];
          const isActive = step === s;
          const isDone = (['upload', 'review', 'saving', 'done'] as UploadStep[]).indexOf(step) > idx;
          return (
            <div key={s} className="flex items-center gap-2">
              <div className="flex items-center gap-2">
                <div className="w-7 h-7 rounded-full flex items-center justify-center text-xs font-bold" style={{ backgroundColor: isDone ? 'hsl(var(--success))' : isActive ? 'hsl(var(--primary))' : 'hsl(var(--muted))', color: isDone || isActive ? 'white' : 'hsl(var(--muted-foreground))' }}>
                  {isDone ? <Check size={13} /> : idx + 1}
                </div>
                <span className="text-sm font-medium hidden sm:block" style={{ color: isActive ? 'hsl(var(--foreground))' : 'hsl(var(--muted-foreground))' }}>{labels[idx]}</span>
              </div>
              {idx < 3 && <ChevronRight size={14} style={{ color: 'hsl(var(--muted-foreground))' }} />}
            </div>
          );
        })}
      </div>

      {/* Upload step */}
      {step === 'upload' && (
        <div className="max-w-2xl space-y-5">
          <div
            className="border-2 border-dashed rounded-xl p-10 text-center transition-all cursor-pointer"
            style={{ borderColor: dragging ? 'hsl(var(--primary))' : 'hsl(var(--border))', backgroundColor: dragging ? 'hsl(var(--primary-light))' : 'hsl(var(--muted))' }}
            onDragOver={e => { e.preventDefault(); setDragging(true); }}
            onDragLeave={() => setDragging(false)}
            onDrop={handleDrop}
            onClick={() => fileRef.current?.click()}
          >
            <Upload size={36} className="mx-auto mb-4" style={{ color: 'hsl(var(--primary))' }} />
            <h3 className="font-semibold text-base mb-1" style={{ color: 'hsl(var(--foreground))' }}>{t('menuManagement.uploadMenuFile', 'Upload your menu file')}</h3>
            <p className="text-sm mb-4" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('menuManagement.uploadPrompt', 'Drag & drop or click to choose a CSV or JSON file')}</p>
            <div className="flex items-center justify-center gap-4 mb-5">
              {[{ label: 'CSV', color: 'hsl(var(--success))' }, { label: 'JSON', color: 'hsl(var(--info))' }].map(f => (
                <div key={f.label} className="flex items-center gap-1.5 text-sm" style={{ color: 'hsl(var(--foreground-secondary))' }}>
                  <FileText size={16} style={{ color: f.color }} /> {f.label}
                </div>
              ))}
            </div>
            <button className="btn-primary" onClick={e => { e.stopPropagation(); fileRef.current?.click(); }}>
              <Upload size={15} /> {t('menuManagement.chooseFile', 'Choose File')}
            </button>
            <input ref={fileRef} type="file" accept=".csv,.json" className="hidden" onChange={handleInputChange} />
          </div>
          {parseError && (
            <div className="px-4 py-3 rounded-xl text-sm" style={{ backgroundColor: 'hsl(var(--danger-bg))', color: 'hsl(var(--danger))', border: '1px solid hsl(var(--danger-border))' }}>
              {parseError}
            </div>
          )}
          <div className="card p-4">
            <p className="text-xs font-semibold uppercase tracking-wider mb-3" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('menuManagement.howItWorks', 'How it works')}</p>
            <div className="space-y-2">
              {[
                t('menuManagement.step1', 'Upload a CSV (columns: name, price, category, description) or JSON array'),
                t('menuManagement.step2', 'Each row is parsed and shown for review'),
                t('menuManagement.step3', 'Approve, edit, or reject individual items'),
                t('menuManagement.step4', 'Approved items are saved to your menu instantly')
              ].map((s, i) => (
                <div key={i} className="flex items-start gap-3 text-sm" style={{ color: 'hsl(var(--foreground-secondary))' }}>
                  <span className="w-5 h-5 rounded-full flex items-center justify-center text-xs font-bold shrink-0" style={{ backgroundColor: 'hsl(var(--primary-light))', color: 'hsl(var(--primary))' }}>{i + 1}</span>
                  {s}
                </div>
              ))}
            </div>
          </div>
        </div>
      )}

      {/* Review step */}
      {step === 'review' && (
        <div className="space-y-4">
          <div className="flex flex-wrap items-center gap-4 p-4 rounded-xl" style={{ backgroundColor: 'hsl(var(--muted))' }}>
            <span className="font-semibold text-sm" style={{ color: 'hsl(var(--foreground))' }}>{t('menuManagement.itemsFound', '{{count}} items found', { count: items.length })}</span>
            <div className="flex items-center gap-3 ml-auto">
              <span className="badge badge-success">{t('menuManagement.approvedCount', '{{count}} approved', { count: approvedCount })}</span>
              <span className="badge badge-danger">{t('menuManagement.rejectedCount', '{{count}} rejected', { count: rejectedCount })}</span>
              <span className="badge badge-neutral">{t('menuManagement.pendingCount', '{{count}} pending', { count: pendingCount })}</span>
            </div>
            <div className="flex gap-2">
              <button className="btn-secondary text-xs py-1.5" onClick={approveAll}>{t('menuManagement.approveAll', 'Approve All Valid')}</button>
              <button className="btn-secondary text-xs py-1.5" onClick={rejectLow} style={{ color: 'hsl(var(--warning))' }}>
                <AlertTriangle size={12} /> {t('menuManagement.rejectErrors', 'Reject Errors')}
              </button>
            </div>
          </div>
          <div className="card overflow-hidden">
            <table className="w-full">
              <thead>
                <tr style={{ borderBottom: '1px solid hsl(var(--border))' }}>
                  {[
                    t('menuManagement.item', 'Item'),
                    t('menuManagement.category', 'Category'),
                    t('menuManagement.price', 'Price'),
                    t('menuManagement.status', 'Status'),
                    t('menuManagement.actions', 'Actions')
                  ].map(h => (
                    <th key={h} className="text-left px-4 py-3 text-xs font-semibold uppercase tracking-wider" style={{ color: 'hsl(var(--muted-foreground))' }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {items.map((item, idx) => (
                  <tr key={item.id} className="table-row-hover" style={{ borderBottom: idx < items.length - 1 ? '1px solid hsl(var(--border))' : 'none', opacity: item.status === 'rejected' ? 0.5 : 1 }}>
                    <td className="px-4 py-3">
                      {editingId === item.id ? (
                        <input className="input-base text-xs py-1" value={editForm.name ?? item.name} onChange={e => setEditForm(f => ({ ...f, name: e.target.value }))} />
                      ) : (
                        <div>
                          <p className="font-medium text-sm" style={{ color: 'hsl(var(--foreground))' }}>{item.name}</p>
                          {item.description && <p className="text-xs truncate max-w-[200px]" style={{ color: 'hsl(var(--muted-foreground))' }}>{item.description}</p>}
                          {item.error && <p className="text-xs font-semibold mt-0.5" style={{ color: 'hsl(var(--danger))' }}>{item.error}</p>}
                        </div>
                      )}
                    </td>
                    <td className="px-4 py-3">
                      {editingId === item.id
                        ? <input className="input-base text-xs py-1 w-24" value={editForm.category ?? item.category} onChange={e => setEditForm(f => ({ ...f, category: e.target.value }))} />
                        : <span className="badge badge-neutral">{item.category}</span>}
                    </td>
                    <td className="px-4 py-3 font-semibold tabular-nums text-sm" style={{ color: 'hsl(var(--foreground))' }}>
                      {editingId === item.id
                        ? <input type="number" className="input-base text-xs py-1 w-20" value={editForm.price ?? item.price} onChange={e => setEditForm(f => ({ ...f, price: parseFloat(e.target.value) || 0 }))} />
                        : `$${item.price.toFixed(2)}`}
                    </td>
                    <td className="px-4 py-3">
                      <span className={`badge ${item.status === 'approved' ? 'badge-success' : item.status === 'rejected' ? 'badge-danger' : 'badge-neutral'}`}>
                        {item.status === 'approved' ? t('menuManagement.approved', 'approved') : item.status === 'rejected' ? t('menuManagement.rejected', 'rejected') : t('menuManagement.pending', 'pending')}
                      </span>
                    </td>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-1">
                        {editingId === item.id ? (
                          <>
                            <button className="btn-ghost p-1.5" style={{ color: 'hsl(var(--success))' }} onClick={() => { updateItem(item.id, { ...editForm, status: 'approved', error: undefined }); setEditingId(null); setEditForm({}); }}><Check size={14} /></button>
                            <button className="btn-ghost p-1.5" onClick={() => { setEditingId(null); setEditForm({}); }}><X size={14} /></button>
                          </>
                        ) : (
                          <>
                            <button className="btn-ghost p-1.5" style={{ color: 'hsl(var(--success))' }} onClick={() => updateItem(item.id, { status: 'approved' })} title={t('common.approve', 'Approve')}><CheckCircle size={14} /></button>
                            <button className="btn-ghost p-1.5" style={{ color: 'hsl(var(--danger))' }} onClick={() => updateItem(item.id, { status: 'rejected' })} title={t('common.reject', 'Reject')}><XCircle size={14} /></button>
                            <button className="btn-ghost p-1.5" onClick={() => { setEditingId(item.id); setEditForm(item); }} title={t('common.edit', 'Edit')}><Edit2 size={14} /></button>
                          </>
                        )}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div className="flex gap-3">
            <button className="btn-primary" onClick={handleSave} disabled={approvedCount === 0}><Check size={15} /> {t('menuManagement.saveApprovedItems', 'Save {{count}} Approved Items', { count: approvedCount })}</button>
            <button className="btn-secondary" onClick={reset}>{t('menuManagement.startOver', 'Start Over')}</button>
          </div>
        </div>
      )}

      {/* Saving step */}
      {step === 'saving' && (
        <div className="max-w-md mx-auto text-center py-16">
          <div className="w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-6" style={{ backgroundColor: 'hsl(var(--primary-light))' }}>
            <Loader2 size={28} className="animate-spin" style={{ color: 'hsl(var(--primary))' }} />
          </div>
          <h3 className="font-bold text-lg mb-2" style={{ color: 'hsl(var(--foreground))' }}>{t('menuManagement.savingMenuItems', 'Saving menu items…')}</h3>
          <p className="text-sm mb-6" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('menuManagement.addingApprovedItems', 'Adding approved items to your menu')}</p>
          <div className="h-2 rounded-full overflow-hidden mb-2" style={{ backgroundColor: 'hsl(var(--muted))' }}>
            <div className="h-full rounded-full transition-all duration-300" style={{ width: `${savingProgress}%`, backgroundColor: 'hsl(var(--primary))' }} />
          </div>
          <p className="text-xs" style={{ color: 'hsl(var(--muted-foreground))' }}>{t('menuManagement.savingProgress', '{{progress}}% complete', { progress: savingProgress })}</p>
        </div>
      )}

      {/* Done step */}
      {step === 'done' && (
        <div className="max-w-2xl mx-auto py-8">
          <div className="text-center mb-6">
            <div className="w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4" style={{ backgroundColor: 'hsl(var(--success-bg))' }}>
              <CheckCircle size={32} style={{ color: 'hsl(var(--success))' }} />
            </div>
            <h3 className="font-bold text-xl mb-1" style={{ color: 'hsl(var(--foreground))' }}>{t('menuManagement.uploadComplete', 'Upload complete!')}</h3>
            <p className="text-sm" style={{ color: 'hsl(var(--muted-foreground))' }}>
              {t('menuManagement.itemsSaved', '{{count}} items saved', { count: saveResults.filter(r => r.ok).length })}.
              {saveResults.filter(r => !r.ok).length > 0 && ` ${t('menuManagement.itemsFailed', '{{count}} failed', { count: saveResults.filter(r => !r.ok).length })}.`}
            </p>
          </div>
          {saveResults.length > 0 && (
            <div className="card overflow-hidden mb-6">
              <div className="px-4 py-3 text-xs font-semibold uppercase tracking-wider" style={{ borderBottom: '1px solid hsl(var(--border))', color: 'hsl(var(--muted-foreground))' }}>{t('menuManagement.saveResults', 'Save Results')}</div>
              <div className="max-h-64 overflow-y-auto divide-y" style={{ borderColor: 'hsl(var(--border))' }}>
                {saveResults.map((r, i) => (
                  <div key={i} className="flex items-center gap-3 px-4 py-2.5">
                    {r.ok ? <CheckCircle size={14} style={{ color: 'hsl(var(--success))', flexShrink: 0 }} /> : <XCircle size={14} style={{ color: 'hsl(var(--danger))', flexShrink: 0 }} />}
                    <span className="flex-1 text-sm truncate" style={{ color: 'hsl(var(--foreground))' }}>{r.item.name}</span>
                    {r.ok ? <span className="text-xs" style={{ color: 'hsl(var(--success))' }}>{t('menuManagement.saved', 'Saved')}</span> : <span className="text-xs truncate max-w-48" style={{ color: 'hsl(var(--danger))' }}>{r.error}</span>}
                  </div>
                ))}
              </div>
            </div>
          )}
          <div className="flex gap-3 justify-center">
            <button className="btn-secondary" onClick={reset}>{t('menuManagement.uploadAnother', 'Upload Another')}</button>
          </div>
        </div>
      )}
    </>
  );
}
