
import React, { useState, useRef } from 'react';
import * as XLSX from 'xlsx';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Progress } from '@/components/ui/progress';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Upload, FileText, AlertTriangle, CheckCircle, Shield, X, Download } from 'lucide-react';
import { useAuth } from '@/contexts/AuthContext';
import { useToast } from '@/hooks/use-toast';
import { validateExpenseImport } from '@/lib/expenseImportValidator';
import { logExpenseAudit } from '@/lib/expenseAuditLogger';
import { supabase } from '@/integrations/supabase/client';

export function SecureExpenseImportDialog({ open, onOpenChange, onSuccess, validCategories, clientId }) {
  const { user } = useAuth();
  const { toast } = useToast();
  const fileInputRef = useRef(null);

  const [file, setFile] = useState(null);
  const [analyzing, setAnalyzing] = useState(false);
  const [importing, setImporting] = useState(false);
  const [validationResult, setValidationResult] = useState(null);
  const [progress, setProgress] = useState(0);

  const handleFileChange = (e) => {
    const selectedFile = e.target.files[0];
    if (selectedFile) {
        const type = selectedFile.name.split('.').pop().toLowerCase();
        if (!['csv', 'xlsx', 'xls'].includes(type)) {
            toast({ variant: "destructive", title: "Invalid File Type", description: "Please upload CSV or Excel files only." });
            return;
        }
        if (selectedFile.size > 10 * 1024 * 1024) {
             toast({ variant: "destructive", title: "File Too Large", description: "Max file size is 10MB." });
             return;
        }
        setFile(selectedFile);
        setValidationResult(null);
    }
  };

  const analyzeFile = async () => {
    if (!file) return;
    setAnalyzing(true);
    
    const reader = new FileReader();
    reader.onload = async (e) => {
        try {
            const data = e.target.result;
            let jsonData = [];
            
            if (file.name.endsWith('.csv')) {
                 const workbook = XLSX.read(data, { type: 'binary' });
                 jsonData = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);
            } else {
                 const workbook = XLSX.read(data, { type: 'binary' });
                 jsonData = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);
            }

            const normalizedData = jsonData.map(row => {
                const newRow = {};
                Object.keys(row).forEach(key => {
                    newRow[key.toLowerCase().trim().replace(/\s+/g, '_')] = row[key];
                });
                return newRow;
            });

            const categorySet = new Set(validCategories.map(c => c.category_name));
            const result = validateExpenseImport(normalizedData, categorySet, clientId);
            
            setValidationResult(result);
            
            if (!result.valid) {
                await logExpenseAudit({
                    userId: user.id,
                    action: 'IMPORT_VALIDATION_FAILURE',
                    status: 'FAILURE',
                    details: {
                        fileName: file.name,
                        errorCount: result.errors.length,
                        firstError: result.errors[0]
                    }
                });
            }

        } catch (err) {
            console.error(err);
            toast({ variant: "destructive", title: "Analysis Error", description: "Failed to parse file." });
        } finally {
            setAnalyzing(false);
        }
    };
    reader.readAsBinaryString(file);
  };

  const executeImport = async () => {
    if (!validationResult || !validationResult.valid) return;
    
    setImporting(true);
    setProgress(10);

    try {
        const records = validationResult.sanitizedRecords;
        const batchSize = 50;
        const total = records.length;
        
        for (let i = 0; i < total; i += batchSize) {
            const batch = records.slice(i, i + batchSize).map(r => ({
                ...r,
                created_by: user.id,
                status: 'pending',
                created_at: new Date().toISOString()
            }));
            
            const { error } = await supabase.from('billable_expenses').insert(batch);
            if (error) throw error;
            
            setProgress(10 + Math.round(((i + batchSize) / total) * 90));
        }

        await logExpenseAudit({
            userId: user.id,
            action: 'IMPORT_SUCCESS',
            status: 'SUCCESS',
            details: { fileName: file.name, recordCount: total }
        });

        toast({ title: "Import Successful", description: `Imported ${total} expenses.` });
        if (onSuccess) onSuccess();
        onOpenChange(false);

    } catch (err) {
        console.error(err);
        toast({ variant: "destructive", title: "Import Failed", description: err.message });
        
        await logExpenseAudit({
            userId: user.id,
            action: 'IMPORT_FAILURE',
            status: 'FAILURE',
            details: { fileName: file.name, error: err.message }
        });
    } finally {
        setImporting(false);
        setProgress(0);
    }
  };

  const downloadTemplate = () => {
    const headers = ['amount', 'date', 'description', 'category', 'client_id', 'billable_type', 'unit_price', 'quantity', 'address'];
    const ws = XLSX.utils.aoa_to_sheet([headers]);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "Template");
    XLSX.writeFile(wb, "expense_import_template.xlsx");
  };

  return (
    <Dialog open={open} onOpenChange={(val) => {
        if (!importing) {
            setFile(null);
            setValidationResult(null);
            onOpenChange(val);
        }
    }}>
      <DialogContent className="sm:max-w-[600px]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Shield className="w-5 h-5 text-primary" />
            Secure Expense Import
          </DialogTitle>
          <DialogDescription>
            Import expenses from CSV/Excel. Data is validated for security and integrity.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-2">
            {!file ? (
                <div className="border-2 border-dashed border-border rounded-lg p-8 flex flex-col items-center justify-center text-center hover:bg-muted/50 transition-colors">
                    <Upload className="w-10 h-10 text-muted-foreground mb-4" />
                    <h3 className="font-medium text-foreground">Upload Expense File</h3>
                    <p className="text-sm text-muted-foreground mb-4">CSV or Excel (max 10MB)</p>
                    <div className="flex gap-2">
                        <Button variant="outline" onClick={() => fileInputRef.current?.click()}>
                            Select File
                        </Button>
                        <Button variant="ghost" size="sm" onClick={downloadTemplate} title="Download Template">
                             <Download className="w-4 h-4" />
                        </Button>
                    </div>
                    <input 
                        type="file" 
                        ref={fileInputRef} 
                        className="hidden" 
                        accept=".csv, .xlsx, .xls"
                        onChange={handleFileChange}
                    />
                </div>
            ) : (
                <div className="space-y-4">
                    <div className="flex items-center justify-between p-3 bg-muted/50 rounded border">
                        <div className="flex items-center gap-3">
                            <FileText className="w-5 h-5 text-primary" />
                            <span className="font-medium text-sm truncate max-w-[300px]">{file.name}</span>
                        </div>
                        <Button variant="ghost" size="icon" onClick={() => { setFile(null); setValidationResult(null); }} disabled={importing || analyzing}>
                            <X className="w-4 h-4" />
                        </Button>
                    </div>

                    {!validationResult && (
                        <Button onClick={analyzeFile} disabled={analyzing} className="w-full">
                            {analyzing ? "Analyzing..." : "Validate & Preview"}
                        </Button>
                    )}

                    {validationResult && (
                        <div className="animate-in fade-in slide-in-from-top-2">
                            {validationResult.valid ? (
                                <Alert className="bg-emerald-50 border-emerald-200">
                                    <CheckCircle className="h-4 w-4 text-emerald-600" />
                                    <AlertTitle className="text-emerald-800">Validation Passed</AlertTitle>
                                    <AlertDescription className="text-emerald-700">
                                        Ready to import {validationResult.sanitizedRecords.length} records.
                                    </AlertDescription>
                                </Alert>
                            ) : (
                                <Alert variant="destructive">
                                    <AlertTriangle className="h-4 w-4" />
                                    <AlertTitle>Validation Failed</AlertTitle>
                                    <AlertDescription>
                                        Found {validationResult.errors.length} issues. Import blocked.
                                    </AlertDescription>
                                </Alert>
                            )}

                            {!validationResult.valid && (
                                <ScrollArea className="h-[150px] w-full border rounded mt-2 p-2 bg-destructive/5 text-xs text-destructive">
                                    {validationResult.errors.map((err, i) => (
                                        <div key={i} className="mb-1 border-b border-destructive/10 pb-1 last:border-0">
                                            <strong>Row {err.row}:</strong> {err.messages.join(', ')}
                                        </div>
                                    ))}
                                </ScrollArea>
                            )}
                        </div>
                    )}

                    {importing && (
                        <div className="space-y-1">
                            <div className="flex justify-between text-xs text-muted-foreground">
                                <span>Importing...</span>
                                <span>{progress}%</span>
                            </div>
                            <Progress value={progress} />
                        </div>
                    )}
                </div>
            )}
        </div>

        <DialogFooter>
             <Button variant="ghost" onClick={() => onOpenChange(false)} disabled={importing}>Close</Button>
             {validationResult?.valid && (
                 <Button onClick={executeImport} disabled={importing} className="bg-emerald-600 hover:bg-emerald-700 text-white">
                     {importing ? "Importing..." : "Confirm Import"}
                 </Button>
             )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
