
'use client';

import { useState, useRef } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Upload, MapPin, AlertCircle, CheckCircle2, X } from 'lucide-react';
import { toast } from 'sonner';

interface GPSFileUploadProps {
  uploadType: string;
  leadId?: string;
  contractId?: string;
  quoteId?: string;
  expectedLatitude?: number;
  expectedLongitude?: number;
  onUploadComplete?: (upload: any) => void;
  requireGPS?: boolean;
}

export function GPSFileUpload({
  uploadType,
  leadId,
  contractId,
  quoteId,
  expectedLatitude,
  expectedLongitude,
  onUploadComplete,
  requireGPS = true
}: GPSFileUploadProps) {
  const [files, setFiles] = useState<File[]>([]);
  const [uploading, setUploading] = useState(false);
  const [gpsData, setGpsData] = useState<any>(null);
  const [gpsError, setGpsError] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const captureGPS = () => {
    return new Promise<GeolocationPosition>((resolve, reject) => {
      if (!navigator.geolocation) {
        reject(new Error('Geolocation is not supported by your browser'));
        return;
      }

      navigator.geolocation.getCurrentPosition(
        (position) => {
          resolve(position);
        },
        (error) => {
          let errorMessage = 'Failed to get GPS location';
          switch (error.code) {
            case error.PERMISSION_DENIED:
              errorMessage = 'Location permission denied. Please enable location access.';
              break;
            case error.POSITION_UNAVAILABLE:
              errorMessage = 'Location information unavailable.';
              break;
            case error.TIMEOUT:
              errorMessage = 'Location request timed out.';
              break;
          }
          reject(new Error(errorMessage));
        },
        {
          enableHighAccuracy: true,
          timeout: 10000,
          maximumAge: 0
        }
      );
    });
  };

  const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFiles = Array.from(e.target.files || []);
    if (selectedFiles.length === 0) return;

    setFiles(selectedFiles);

    if (requireGPS) {
      try {
        const position = await captureGPS();
        setGpsData({
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
          accuracy: position.coords.accuracy,
          altitude: position.coords.altitude,
          timestamp: new Date().toISOString()
        });
        setGpsError(null);
        toast.success('GPS location captured successfully');
      } catch (error: any) {
        setGpsError(error.message);
        toast.error(error.message);
        setFiles([]);
      }
    }
  };

  const handleUpload = async () => {
    if (files.length === 0) {
      toast.error('Please select files to upload');
      return;
    }

    if (requireGPS && !gpsData) {
      toast.error('GPS location is required for this upload');
      return;
    }

    setUploading(true);

    try {
      const uploads = [];
      
      for (const file of files) {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('uploadType', uploadType);
        
        if (leadId) formData.append('leadId', leadId);
        if (contractId) formData.append('contractId', contractId);
        if (quoteId) formData.append('quoteId', quoteId);
        
        if (gpsData) {
          formData.append('latitude', gpsData.latitude.toString());
          formData.append('longitude', gpsData.longitude.toString());
          formData.append('accuracy', gpsData.accuracy?.toString() || '0');
          formData.append('altitude', gpsData.altitude?.toString() || '0');
          formData.append('gpsTimestamp', gpsData.timestamp);
        }
        
        if (expectedLatitude) formData.append('expectedLatitude', expectedLatitude.toString());
        if (expectedLongitude) formData.append('expectedLongitude', expectedLongitude.toString());

        const response = await fetch('/api/uploads', {
          method: 'POST',
          body: formData
        });

        if (response.ok) {
          const data = await response.json();
          uploads.push(data.upload);
        } else {
          throw new Error('Upload failed');
        }
      }

      toast.success(`${uploads.length} file(s) uploaded successfully`);
      setFiles([]);
      setGpsData(null);
      
      if (onUploadComplete) {
        uploads.forEach((upload) => onUploadComplete(upload));
      }
    } catch (error) {
      console.error('Error uploading files:', error);
      toast.error('Failed to upload files');
    } finally {
      setUploading(false);
    }
  };

  const removeFile = (index: number) => {
    setFiles(files.filter((_, i) => i !== index));
    if (files.length === 1) {
      setGpsData(null);
    }
  };

  return (
    <div className="space-y-4">
      <Card>
        <CardContent className="pt-6">
          <div className="space-y-4">
            {requireGPS && (
              <div className="flex items-start gap-2 p-3 bg-blue-50 border border-blue-200 rounded-lg">
                <MapPin className="w-5 h-5 text-blue-600 mt-0.5" />
                <div className="text-sm">
                  <p className="font-semibold text-blue-900 mb-1">GPS Location Required</p>
                  <p className="text-blue-800">
                    Your GPS location will be captured when you select files to ensure
                    photos are taken at the correct job site.
                  </p>
                </div>
              </div>
            )}

            <div className="border-2 border-dashed rounded-lg p-8 text-center">
              <input
                ref={fileInputRef}
                type="file"
                multiple
                onChange={handleFileSelect}
                className="hidden"
                accept="image/*,.pdf,.dwg"
              />
              <Upload className="w-12 h-12 mx-auto mb-4 text-muted-foreground" />
              <h3 className="text-lg font-semibold mb-2">Upload Files</h3>
              <p className="text-sm text-muted-foreground mb-4">
                Click to select files or drag and drop
              </p>
              <Button
                type="button"
                variant="outline"
                onClick={() => fileInputRef.current?.click()}
              >
                Select Files
              </Button>
            </div>

            {gpsError && (
              <div className="flex items-start gap-2 p-3 bg-red-50 border border-red-200 rounded-lg">
                <AlertCircle className="w-5 h-5 text-red-600 mt-0.5" />
                <div className="text-sm">
                  <p className="font-semibold text-red-900 mb-1">GPS Error</p>
                  <p className="text-red-800">{gpsError}</p>
                </div>
              </div>
            )}

            {gpsData && (
              <div className="flex items-start gap-2 p-3 bg-green-50 border border-green-200 rounded-lg">
                <CheckCircle2 className="w-5 h-5 text-green-600 mt-0.5" />
                <div className="text-sm flex-1">
                  <p className="font-semibold text-green-900 mb-1">GPS Location Captured</p>
                  <div className="text-green-800 space-y-1">
                    <p>Latitude: {gpsData.latitude.toFixed(6)}</p>
                    <p>Longitude: {gpsData.longitude.toFixed(6)}</p>
                    <p>Accuracy: ±{gpsData.accuracy.toFixed(0)} meters</p>
                  </div>
                </div>
              </div>
            )}

            {files.length > 0 && (
              <div className="space-y-2">
                <h4 className="font-semibold">Selected Files:</h4>
                {files.map((file, index) => (
                  <div
                    key={index}
                    className="flex items-center justify-between p-3 bg-muted rounded-lg"
                  >
                    <div className="flex items-center gap-2">
                      <Badge variant="secondary">{file.type.split('/')[1]?.toUpperCase() || 'FILE'}</Badge>
                      <span className="text-sm">{file.name}</span>
                      <span className="text-xs text-muted-foreground">
                        ({(file.size / 1024 / 1024).toFixed(2)} MB)
                      </span>
                    </div>
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => removeFile(index)}
                    >
                      <X className="w-4 h-4" />
                    </Button>
                  </div>
                ))}
              </div>
            )}

            {files.length > 0 && (
              <Button
                onClick={handleUpload}
                disabled={uploading || (requireGPS && !gpsData)}
                className="w-full"
              >
                {uploading ? 'Uploading...' : `Upload ${files.length} File(s)`}
              </Button>
            )}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
