
import React, { useState, useRef } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Upload, FileUp, AlertCircle, CheckCircle2, Download, XCircle, RefreshCw } from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
import { supabase } from '@/integrations/supabase/client';
import { usePayables } from '@/hooks/usePayables';
import * as XLSX from 'xlsx';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Badge } from '@/components/ui/badge';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';

export function PayablesImportDialog({ onImport }) {
  const [open, setOpen] = useState(false);
  const [step, setStep] = useState('upload');
  const [file, setFile] = useState(null);
  const [validRows, setValidRows] = useState([]);
  const [validationErrors, setValidationErrors] = useState([]);
  const [loading, setLoading] = useState(false);
  const [clients, setClients] = useState([]);
  const fileInputRef = useRef(null);
  const { toast } = useToast();
  const { bulkAddPayables } = usePayables();

  const handleOpenChange = (newOpen) => {
    setOpen(newOpen);
    if (!newOpen) {
      setTimeout(() => { setStep('upload'); setFile(null); setValidRows([]); setValidationErrors([]); }, 300);
    } else {
      fetchClients();
    }
  };

  const fetchClients = async () => {
    try {
      const { data, error } = await supabase.from('associations').select('id, name').eq('status', 'active');
      if (error) throw error;
      if (data) setClients(data);
    } catch (err) {
      console.error("Failed to fetch associations for import matching", err);
      toast({ variant: "destructive", title: "Warning", description: "Could not load association list." });
    }
  };

  const handleFileChange = (e) => {
    const selectedFile = e.target.files[0];
    if (selectedFile) { setFile(selectedFile); parseFile(selectedFile); }
  };

  const KNOWN_HEADERS = {
    bill_date: ['bill date', 'billdate', 'date', 'invoice date', 'inv date'],
    due_date: ['due date', 'duedate', 'due'],
    payee: ['payee', 'vendor', 'company', 'recipient', 'supplier'],
    client_name: ['client', 'association', 'client association', 'property', 'client-association', 'community'],
    amount: ['amount', 'total', 'cost', 'price', 'balance', 'total amount'],
    expense_account: ['expense account', 'account', 'category', 'gl code', 'expense', 'account number']
  };

  const mapHeaders = (headerRow) => {
    const map = {};
    headerRow.forEach((h, index) => {
      if (!h) return;
      const text = String(h).toLowerCase().trim();
      for (const [key, variations] of Object.entries(KNOWN_HEADERS)) {
        if (variations.some(v => text === v || text.includes(v))) {
          if (map[key] === undefined) map[key] = index;
        }
      }
    });
    return map;
  };

  const validateImportData = async (rawRows, clientsList) => {
    const validRows = [];
    const errors = [];

    rawRows.forEach((row, index) => {
      if (!row.payee) { errors.push({ row: index + 2, error: 'Missing payee' }); return; }
      if (!row.amount || isNaN(parseFloat(row.amount))) { errors.push({ row: index + 2, error: 'Invalid amount' }); return; }

      let clientId = null;
      if (row.client_name) {
        const match = clientsList.find(c => c.name.toLowerCase() === String(row.client_name).toLowerCase().trim());
        if (match) clientId = match.id;
      }

      validRows.push({
        bill_date: row.bill_date || null,
        due_date: row.due_date || null,
        payee: String(row.payee).trim(),
        amount: parseFloat(row.amount),
        expense_account: row.expense_account || null,
        client_id: clientId
      });
    });

    return { validRows, errors };
  };

  const parseFile = (file) => {
    setLoading(true);
    const reader = new FileReader();
    reader.onload = async (e) => {
      try {
        const data = new Uint8Array(e.target.result);
        const workbook = XLSX.read(data, { type: 'array' });
        const sheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[sheetName];
        const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

        if (!jsonData || jsonData.length < 2) {
          toast({ variant: "destructive", title: "Empty File", description: "File contains no data rows." });
          setLoading(false); setFile(null); return;
        }

        const headerRow = jsonData[0];
        const colMap = mapHeaders(headerRow);

        const missingCols = [];
        if (colMap.payee === undefined) missingCols.push('Payee');
        if (colMap.amount === undefined) missingCols.push('Amount');

        if (missingCols.length > 0) {
          toast({ variant: "destructive", title: "Invalid Format", description: `Could not find required columns: ${missingCols.join(', ')}.` });
          setLoading(false); setFile(null); return;
        }

        const rawRows = jsonData.slice(1).map(row => {
          const getValue = (idx) => idx !== undefined && row[idx] !== undefined ? row[idx] : null;
          return {
            bill_date: getValue(colMap.bill_date), due_date: getValue(colMap.due_date),
            payee: getValue(colMap.payee), client_name: getValue(colMap.client_name),
            amount: getValue(colMap.amount), expense_account: getValue(colMap.expense_account)
          };
        }).filter(r => r.payee || r.amount);

        const { validRows: vRows, errors } = await validateImportData(rawRows, clients);
        setValidRows(vRows);
        setValidationErrors(errors);
        setStep('preview');
      } catch (err) {
        console.error("Parse Error", err);
        toast({ variant: "destructive", title: "Error", description: "Failed to parse file." });
        setFile(null);
      } finally {
        setLoading(false);
      }
    };
    reader.onerror = () => { toast({ variant: "destructive", title: "Error", description: "Failed to read file." }); setLoading(false); setFile(null); };
    reader.readAsArrayBuffer(file);
  };

  const processImport = async () => {
    if (validRows.length === 0) return;
    setLoading(true);
    try {
      if (onImport) await onImport(validRows);
      else await bulkAddPayables(validRows);
      setStep('results');
      toast({ title: "Success", description: "Import completed successfully." });
    } catch (err) {
      console.error(err);
    } finally {
      setLoading(false);
    }
  };

  const downloadTemplate = () => {
    const headers = ['Bill Date', 'Due Date', 'Payee', 'Client Association', 'Expense Account', 'Amount'];
    const sample = ['2024-05-15', '2024-06-15', 'Sample Vendor Inc.', 'Sunset Villas', '5010 - Utilities', '150.00'];
    const ws = XLSX.utils.aoa_to_sheet([headers, sample]);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "Payables Template");
    XLSX.writeFile(wb, "Payables_Import_Template.xlsx");
  };

  const renderUploadStep = () => (
    <div className="space-y-6 py-4">
      <div className="flex flex-col items-center justify-center border-2 border-dashed border-border rounded-lg p-8 bg-muted/50 transition-colors hover:bg-muted hover:border-muted-foreground/30">
        <FileUp className="w-12 h-12 text-muted-foreground mb-4" />
        <div className="text-center space-y-3">
          <Button onClick={() => fileInputRef.current?.click()} disabled={loading}>
            {loading ? <RefreshCw className="w-4 h-4 animate-spin mr-2" /> : null}
            {loading ? 'Processing...' : 'Select File to Import'}
          </Button>
          <p className="text-sm text-muted-foreground">Supports CSV, Excel (.xlsx, .xls)</p>
          <input type="file" ref={fileInputRef} className="hidden" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" onChange={handleFileChange} />
        </div>
      </div>
      <div className="bg-primary/5 p-4 rounded-md border border-primary/10 text-sm space-y-2 text-foreground">
        <div className="flex items-center gap-2 font-semibold"><AlertCircle className="w-4 h-4" /> Import Guide</div>
        <ul className="list-disc list-inside space-y-1 ml-1 opacity-90 text-xs">
          <li>Required: <strong>Payee, Amount</strong></li>
          <li>Optional: Bill Date, Due Date, Client Association, Expense Account</li>
          <li>Date format: MM/DD/YYYY or YYYY-MM-DD</li>
        </ul>
        <div className="pt-2">
          <Button variant="link" onClick={downloadTemplate} className="h-auto p-0 gap-1 font-semibold text-xs">
            <Download className="w-3 h-3" /> Download Standard Template
          </Button>
        </div>
      </div>
    </div>
  );

  const renderPreviewStep = () => (
    <div className="space-y-4 py-2">
      <div className="flex items-center justify-between">
        <h3 className="text-sm font-semibold">Import Summary</h3>
        <div className="flex gap-2 text-sm">
          <Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-200">{validRows.length} Valid Rows</Badge>
          {validationErrors.length > 0 && <Badge variant="outline" className="bg-destructive/10 text-destructive border-destructive/20">{validationErrors.length} Errors</Badge>}
        </div>
      </div>
      {validationErrors.length > 0 && (
        <Alert variant="destructive" className="py-2">
          <AlertCircle className="h-4 w-4" />
          <AlertTitle>Attention Needed</AlertTitle>
          <AlertDescription className="text-xs mt-1">{validationErrors.length} rows were skipped due to errors.</AlertDescription>
        </Alert>
      )}
      <div className="border rounded-md overflow-hidden">
        <Table>
          <TableHeader className="bg-muted">
            <TableRow><TableHead className="w-[40px]"></TableHead><TableHead>Bill Date</TableHead><TableHead>Payee</TableHead><TableHead>Association</TableHead><TableHead>Amount</TableHead></TableRow>
          </TableHeader>
        </Table>
        <ScrollArea className="h-[300px]">
          <Table>
            <TableBody>
              {validationErrors.map((err, i) => (
                <TableRow key={`err-${i}`} className="bg-destructive/5 hover:bg-destructive/10">
                  <TableCell><XCircle className="w-4 h-4 text-destructive" /></TableCell>
                  <TableCell colSpan={4} className="text-destructive text-xs font-medium">Row {err.row}: {err.error}</TableCell>
                </TableRow>
              ))}
              {validRows.map((row, i) => {
                const clientName = clients.find(c => c.id === row.client_id)?.name || (row.client_id ? 'Unknown ID' : 'Unassigned');
                return (
                  <TableRow key={`valid-${i}`} className="hover:bg-muted/50">
                    <TableCell><CheckCircle2 className="w-4 h-4 text-emerald-500" /></TableCell>
                    <TableCell className="text-xs font-mono text-muted-foreground">{row.bill_date || '-'}</TableCell>
                    <TableCell className="font-medium text-xs">{row.payee}</TableCell>
                    <TableCell className="text-xs text-muted-foreground truncate max-w-[120px]" title={clientName}>{clientName}</TableCell>
                    <TableCell className="text-xs font-mono">${row.amount}</TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </ScrollArea>
      </div>
    </div>
  );

  const renderResultsStep = () => (
    <div className="py-8 flex flex-col items-center text-center space-y-4">
      <div className="w-16 h-16 bg-emerald-100 text-emerald-600 rounded-full flex items-center justify-center animate-in zoom-in duration-300">
        <CheckCircle2 className="w-8 h-8" />
      </div>
      <div>
        <h3 className="text-lg font-bold">Import Complete</h3>
        <p className="text-muted-foreground">Successfully imported {validRows.length} payables.</p>
      </div>
      <Button onClick={() => handleOpenChange(false)} className="min-w-[120px]">Close</Button>
    </div>
  );

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogTrigger asChild>
        <Button variant="outline" className="gap-2"><Upload className="w-4 h-4" /> Import Payables</Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-[700px]">
        <DialogHeader>
          <DialogTitle>
            {step === 'upload' && 'Import Payables'}
            {step === 'preview' && 'Review Data'}
            {step === 'results' && 'Import Results'}
          </DialogTitle>
        </DialogHeader>
        {step === 'upload' && renderUploadStep()}
        {step === 'preview' && renderPreviewStep()}
        {step === 'results' && renderResultsStep()}
        {step === 'preview' && (
          <DialogFooter className="gap-2 sm:justify-between border-t pt-4">
            <Button variant="ghost" onClick={() => { setStep('upload'); setFile(null); }}>Back to Upload</Button>
            <div className="flex gap-2">
              <Button variant="outline" onClick={() => handleOpenChange(false)}>Cancel</Button>
              <Button onClick={processImport} disabled={loading || validRows.length === 0}>
                {loading ? 'Importing...' : `Import ${validRows.length} Payables`}
              </Button>
            </div>
          </DialogFooter>
        )}
      </DialogContent>
    </Dialog>
  );
}
