import React, { useState, useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { 
  Upload, 
  Download, 
  FileSpreadsheet, 
  CheckCircle, 
  XCircle, 
  AlertTriangle,
  Loader2
} from 'lucide-react';
import * as XLSX from 'xlsx';
import { AssetCreateRequest, ASSET_TYPES, ASSET_CONDITIONS, BulkImportResponse } from '@/types/asset-management';
import ImportResults from './ImportResults';

interface ImportResult {
  success: boolean;
  data?: AssetCreateRequest[];
  errors?: string[];
  warnings?: string[];
  totalRows?: number;
  validRows?: number;
}

interface ExcelImportProps {
  onImport: (assets: AssetCreateRequest[]) => Promise<BulkImportResponse>;
  isImporting?: boolean;
}

const ExcelImport: React.FC<ExcelImportProps> = ({
  onImport,
  isImporting = false
}) => {
  const [file, setFile] = useState<File | null>(null);
  const [importResult, setImportResult] = useState<ImportResult | null>(null);
  const [apiResult, setApiResult] = useState<BulkImportResponse | null>(null);
  const [isProcessing, setIsProcessing] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Template data for Excel generation
  const generateTemplate = () => {
    const templateData = [
      {
        'Asset Type': 'Laptop',
        'Brand/Model': 'Dell Latitude 5430',
        'Serial Number': 'DL5430-001',
        'Asset Condition': 'Excellent',
        'Purchase Date': '2024-01-15',
        'Warranty Expiry': '2027-01-15',
        'Purchase Cost': '1200.00',
        'Current Value': '1000.00',
        'Location': 'Office Floor 1',
        'Notes': 'Primary development laptop'
      },
      {
        'Asset Type': 'Extended Screen',
        'Brand/Model': 'Samsung 27" 4K',
        'Serial Number': 'SM27-4K-002',
        'Asset Condition': 'Good',
        'Purchase Date': '2024-02-01',
        'Warranty Expiry': '2027-02-01',
        'Purchase Cost': '400.00',
        'Current Value': '350.00',
        'Location': 'Office Floor 2',
        'Notes': 'External monitor for workstation'
      },
      {
        'Asset Type': 'Wireless Mouse',
        'Brand/Model': 'Logitech MX Master 3',
        'Serial Number': 'LG-MX3-003',
        'Asset Condition': 'Excellent',
        'Purchase Date': '2024-03-01',
        'Warranty Expiry': '2026-03-01',
        'Purchase Cost': '99.99',
        'Current Value': '80.00',
        'Location': 'Office Floor 1',
        'Notes': 'Ergonomic wireless mouse'
      },
      {
        'Asset Type': 'Laptop Stand',
        'Brand/Model': 'Rain Design mStand',
        'Serial Number': 'RD-MS-004',
        'Asset Condition': 'Good',
        'Purchase Date': '2024-03-15',
        'Warranty Expiry': '2026-03-15',
        'Purchase Cost': '59.99',
        'Current Value': '50.00',
        'Location': 'Office Floor 1',
        'Notes': 'Aluminum laptop stand for ergonomics'
      }
    ];

    const ws = XLSX.utils.json_to_sheet(templateData);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'Assets Template');

    // Set column widths
    const colWidths = [
      { wch: 15 }, // Asset Type
      { wch: 25 }, // Brand/Model
      { wch: 20 }, // Serial Number
      { wch: 15 }, // Asset Condition
      { wch: 15 }, // Purchase Date
      { wch: 15 }, // Warranty Expiry
      { wch: 12 }, // Purchase Cost
      { wch: 12 }, // Current Value
      { wch: 20 }, // Location
      { wch: 30 }  // Notes
    ];
    ws['!cols'] = colWidths;

    XLSX.writeFile(wb, 'assets_import_template.xlsx');
  };

  const validateAssetData = (data: any[]): ImportResult => {
    const errors: string[] = [];
    const warnings: string[] = [];
    const validAssets: AssetCreateRequest[] = [];

    data.forEach((row, index) => {
      const rowNum = index + 2; // +2 because Excel is 1-indexed and we skip header
      const asset: Partial<AssetCreateRequest> = {};

      // Required fields validation
      if (!row['Asset Type']) {
        errors.push(`Row ${rowNum}: Asset Type is required`);
        return;
      }
      if (!ASSET_TYPES.includes(row['Asset Type'])) {
        errors.push(`Row ${rowNum}: Invalid Asset Type "${row['Asset Type']}". Must be one of: ${ASSET_TYPES.join(', ')}`);
        return;
      }
      asset.assetType = String(row['Asset Type']).trim();

      if (!row['Brand/Model']) {
        errors.push(`Row ${rowNum}: Brand/Model is required`);
        return;
      }
      asset.brandModel = String(row['Brand/Model']).trim();

      if (!row['Serial Number']) {
        errors.push(`Row ${rowNum}: Serial Number is required`);
        return;
      }
      // Convert serialNumber to string (handles numbers, strings, etc.)
      asset.serialNumber = String(row['Serial Number']).trim();

      if (!row['Asset Condition']) {
        errors.push(`Row ${rowNum}: Asset Condition is required`);
        return;
      }
      if (!ASSET_CONDITIONS.includes(row['Asset Condition'])) {
        errors.push(`Row ${rowNum}: Invalid Asset Condition "${row['Asset Condition']}". Must be one of: ${ASSET_CONDITIONS.join(', ')}`);
        return;
      }
      asset.assetCondition = String(row['Asset Condition']).trim();

      // Optional fields with validation
      if (row['Purchase Date']) {
        const purchaseDate = new Date(row['Purchase Date']);
        if (isNaN(purchaseDate.getTime())) {
          warnings.push(`Row ${rowNum}: Invalid Purchase Date format`);
        } else {
          asset.purchaseDate = purchaseDate.toISOString().split('T')[0];
        }
      }

      if (row['Warranty Expiry']) {
        const warrantyExpiry = new Date(row['Warranty Expiry']);
        if (isNaN(warrantyExpiry.getTime())) {
          warnings.push(`Row ${rowNum}: Invalid Warranty Expiry format`);
        } else {
          asset.warrantyExpiry = warrantyExpiry.toISOString().split('T')[0];
        }
      }

      if (row['Purchase Cost']) {
        const cost = parseFloat(row['Purchase Cost']);
        if (isNaN(cost) || cost < 0) {
          warnings.push(`Row ${rowNum}: Invalid Purchase Cost`);
        } else {
          asset.purchaseCost = cost;
        }
      }

      if (row['Current Value']) {
        const value = parseFloat(row['Current Value']);
        if (isNaN(value) || value < 0) {
          warnings.push(`Row ${rowNum}: Invalid Current Value`);
        } else {
          asset.currentValue = value;
        }
      }

      if (row['Location']) {
        asset.location = String(row['Location']).trim();
      }

      if (row['Notes']) {
        asset.notes = String(row['Notes']).trim();
      }

      validAssets.push(asset as AssetCreateRequest);
    });

    return {
      success: errors.length === 0,
      data: validAssets,
      errors,
      warnings,
      totalRows: data.length,
      validRows: validAssets.length
    };
  };

  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFile = event.target.files?.[0];
    if (selectedFile) {
      setFile(selectedFile);
      setImportResult(null);
    }
  };

  const processFile = async () => {
    if (!file) return;

    setIsProcessing(true);
    try {
      const data = await file.arrayBuffer();
      const workbook = XLSX.read(data);
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];
      const jsonData = XLSX.utils.sheet_to_json(worksheet);

      if (jsonData.length === 0) {
        setImportResult({
          success: false,
          errors: ['The Excel file appears to be empty or has no data rows.']
        });
        return;
      }

      const result = validateAssetData(jsonData);
      setImportResult(result);
    } catch (error) {
      setImportResult({
        success: false,
        errors: ['Failed to process the Excel file. Please ensure it\'s a valid Excel file.']
      });
    } finally {
      setIsProcessing(false);
    }
  };

  const handleImport = async () => {
    if (!importResult?.data) return;
    
    try {
      const result = await onImport(importResult.data);
      setApiResult(result);
      
      // Only clear the form if the import was completely successful
      if (result.success && result.results.failed === 0) {
        setFile(null);
        setImportResult(null);
        if (fileInputRef.current) {
          fileInputRef.current.value = '';
        }
      }
    } catch (error) {
      console.error('Import failed:', error);
    }
  };

  const resetImport = () => {
    setFile(null);
    setImportResult(null);
    setApiResult(null);
    if (fileInputRef.current) {
      fileInputRef.current.value = '';
    }
  };

  return (
    <div className="space-y-6">
      {/* Template Download */}
      <Card>
        <CardHeader className="pb-4">
          <CardTitle className="flex items-center gap-2">
            <FileSpreadsheet className="h-5 w-5" />
            Excel Template
          </CardTitle>
        </CardHeader>
        <CardContent>
          <p className="text-sm text-muted-foreground mb-4">
            Download the Excel template to ensure your data is formatted correctly for import.
          </p>
          <Button 
            onClick={generateTemplate}
            variant="outline"
            className="flex items-center gap-2"
          >
            <Download className="h-4 w-4" />
            Download Template
          </Button>
        </CardContent>
      </Card>

      {/* File Upload */}
      <Card>
        <CardHeader className="pb-4">
          <CardTitle className="flex items-center gap-2">
            <Upload className="h-5 w-5" />
            Upload Excel File
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div>
            <Label htmlFor="excel-file">Select Excel File</Label>
            <Input
              id="excel-file"
              ref={fileInputRef}
              type="file"
              accept=".xlsx,.xls"
              onChange={handleFileSelect}
              className="mt-1"
            />
          </div>

          {file && (
            <div className="flex items-center justify-between p-3 bg-muted rounded-lg">
              <div className="flex items-center gap-2">
                <FileSpreadsheet className="h-4 w-4" />
                <span className="text-sm font-medium">{file.name}</span>
                <Badge variant="secondary">{(file.size / 1024).toFixed(1)} KB</Badge>
              </div>
              <div className="flex gap-2">
                <Button
                  onClick={processFile}
                  disabled={isProcessing}
                  size="sm"
                >
                  {isProcessing ? (
                    <>
                      <Loader2 className="h-3 w-3 mr-1 animate-spin" />
                      Processing...
                    </>
                  ) : (
                    'Process File'
                  )}
                </Button>
                <Button
                  onClick={resetImport}
                  variant="outline"
                  size="sm"
                >
                  Remove
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Import Results */}
      {importResult && (
        <Card>
          <CardHeader className="pb-4">
            <CardTitle className="flex items-center gap-2">
              {importResult.success ? (
                <CheckCircle className="h-5 w-5 text-green-600" />
              ) : (
                <XCircle className="h-5 w-5 text-red-600" />
              )}
              Import Results
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            {/* Summary */}
            <div className="grid grid-cols-2 gap-4">
              <div className="text-center p-3 bg-muted rounded-lg">
                <div className="text-2xl font-bold">{importResult.totalRows || 0}</div>
                <div className="text-sm text-muted-foreground">Total Rows</div>
              </div>
              <div className="text-center p-3 bg-muted rounded-lg">
                <div className="text-2xl font-bold text-green-600">{importResult.validRows || 0}</div>
                <div className="text-sm text-muted-foreground">Valid Rows</div>
              </div>
            </div>

            {/* Errors */}
            {importResult.errors && importResult.errors.length > 0 && (
              <Alert variant="destructive">
                <XCircle className="h-4 w-4" />
                <AlertDescription>
                  <div className="font-medium mb-2">Errors found:</div>
                  <ul className="list-disc list-inside space-y-1 text-sm">
                    {importResult.errors.map((error, index) => (
                      <li key={index}>{error}</li>
                    ))}
                  </ul>
                </AlertDescription>
              </Alert>
            )}

            {/* Warnings */}
            {importResult.warnings && importResult.warnings.length > 0 && (
              <Alert>
                <AlertTriangle className="h-4 w-4" />
                <AlertDescription>
                  <div className="font-medium mb-2">Warnings:</div>
                  <ul className="list-disc list-inside space-y-1 text-sm">
                    {importResult.warnings.map((warning, index) => (
                      <li key={index}>{warning}</li>
                    ))}
                  </ul>
                </AlertDescription>
              </Alert>
            )}

            {/* Import Button */}
            {importResult.success && importResult.data && importResult.data.length > 0 && (
              <div className="flex justify-end gap-2 pt-4">
                <Button
                  onClick={resetImport}
                  variant="outline"
                >
                  Cancel
                </Button>
                <Button
                  onClick={handleImport}
                  disabled={isImporting}
                  className="flex items-center gap-2"
                >
                  {isImporting ? (
                    <>
                      <Loader2 className="h-4 w-4 animate-spin" />
                      Importing...
                    </>
                  ) : (
                    <>
                      <Upload className="h-4 w-4" />
                      Import {importResult.data.length} Assets
                    </>
                  )}
                </Button>
              </div>
            )}
          </CardContent>
        </Card>
      )}

      {/* API Import Results */}
      {apiResult && (
        <ImportResults
          result={apiResult}
          onClose={resetImport}
        />
      )}
    </div>
  );
};

export default ExcelImport;