'use client';

import { useSession } from 'next-auth/react';
import { useState, useEffect, useRef } from 'react';
import { encryptBlob } from '@/lib/encryption';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Progress } from '@/components/ui/progress';
import { Textarea } from '@/components/ui/textarea';
import { Card, CardContent } from '@/components/ui/card';
import { Upload, File, X, Send } from 'lucide-react';
import { toast } from 'sonner';
import { formatFileSize } from '@/lib/utils';
import { Loader2 } from 'lucide-react';

const PLAN_LIMITS = {
  free: {
    maxFileSizeMB: 2048,
    maxMonthlyTransferSizeMB: 10240,
    expiryText: '48 hours after sending',
  },
  rookie: {
    maxFileSizeMB: Infinity,
    maxMonthlyTransferSizeMB: 30720,
    expiryText: '7 days after sending',
  },
  pro: {
    maxFileSizeMB: Infinity,
    maxMonthlyTransferSizeMB: 1024 * 1024,
    expiryText: '30 days after sending',
  },
};

export default function SendPage() {
  const { data: session } = useSession();
  const [files, setFiles] = useState<File[]>([]);
  const [recipient, setRecipient] = useState('');
  const [password, setPassword] = useState('');
  const [message, setMessage] = useState('');
  const [plan, setPlan] = useState<'free' | 'rookie' | 'pro'>('free');
  const [remainingMB, setRemainingMB] = useState(Infinity);
  const [usedMB, setUsedMB] = useState(0);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [uploadStep, setUploadStep] = useState('');
  const [uploadMessage, setUploadMessage] = useState('');
  const dropRef = useRef<HTMLDivElement>(null);
  const totalSize = files.reduce((acc, file) => acc + file.size, 0);
  const totalSizeMB = totalSize / 1024 / 1024;
  const isOverLimit =
    totalSizeMB > PLAN_LIMITS[plan].maxFileSizeMB || totalSizeMB > remainingMB;

  useEffect(() => {
    const fetchPlan = async () => {
      const res = await fetch('/api/usage');
      if (res.ok) {
        const data = await res.json();
        setPlan(data.plan);
        setRemainingMB(data.remainingMB);
        setUsedMB(data.usedMB);
      }
    };
    if (session?.user?.email) fetchPlan();
  }, [session]);

  const handleFileAdd = (newFiles: File[]) => {
    const unique = newFiles.filter(
      (newFile) =>
        !files.find(
          (existing) =>
            existing.name === newFile.name && existing.size === newFile.size
        )
    );
    setFiles((prev) => [...prev, ...unique]);
  };

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!e.target.files) return;
    handleFileAdd(Array.from(e.target.files));
  };

  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.dataTransfer.files) {
      handleFileAdd(Array.from(e.dataTransfer.files));
    }
    dropRef.current?.classList.remove('border-blue-500');
  };

  const removeFile = (index: number) => {
    setFiles((prev) => prev.filter((_, i) => i !== index));
  };

  const fileInputRef = useRef<HTMLInputElement>(null);
  const triggerFileInput = () => fileInputRef.current?.click();

  const handleSubmit = async () => {
    if (!files.length)
      return setUploadMessage('Please select at least one file');
    if (!recipient || !password)
      return setUploadMessage('All fields are required');
    if (isOverLimit)
      return setUploadMessage('File size exceeds your plan limits');
    const senderEmail = session?.user?.email;
    if (!senderEmail)
      return setUploadMessage('Unable to get sender email. Please log in.');

    try {
      setUploadStep('Preparing files');
      const file = files[0]; // Upload first file for now

      setUploadStep('Encrypting');
      // Encrypt the file using the password
      const { encryptedBlob } = await encryptBlob(file, password);
      
      // Extract IV from encrypted blob (first 12 bytes)
      const encryptedBytes = new Uint8Array(await encryptedBlob.arrayBuffer());
      const iv = encryptedBytes.slice(0, 12);
      const ivBase64 = btoa(String.fromCharCode(...iv));

      const formData = new FormData();
      formData.append('file', encryptedBlob, file.name + '.enc');
      formData.append('email', recipient);
      formData.append('password', password);
      formData.append('sender', senderEmail);
      formData.append('originalFilename', file.name);
      formData.append('encryptionIv', ivBase64);
      const filenames = files.map((f) => f.name);
      formData.append('filenames', JSON.stringify(filenames));
      formData.append('message', message);

      setUploadProgress(0);
      setUploadStep('Uploading');

      const xhr = new XMLHttpRequest();
      xhr.open('POST', '/api/send');
      xhr.upload.onprogress = (event) => {
        if (event.lengthComputable) {
          const percent = Math.round((event.loaded / event.total) * 100);
          setUploadProgress(percent);
        }
      };

      xhr.onload = () => {
        if (xhr.status === 200) {
          setUploadStep('');
          setUploadMessage('Success! 🎉');
          toast.success('Your transfer has been sent successfully!');
          setFiles([]);
          setRecipient('');
          setPassword('');
          setUploadProgress(100);
          setTimeout(() => setUploadMessage(''), 3000);
        } else {
          setUploadStep('');
          setUploadMessage(`Upload failed: ${xhr.statusText}`);
        }
      };

      xhr.onerror = () => {
        setUploadStep('');
        setUploadMessage('Upload error occurred');
      };

      xhr.send(formData);
    } catch (err: any) {
      console.error(err);
      setUploadStep('');
      setUploadMessage('Error: ' + err.message);
    }
  };

  function UploadStatusToast({
    step,
    progress,
    message,
  }: {
    step: string;
    progress: number;
    message: string;
  }) {
    const showSpinner = ['Zipping', 'Encrypting', 'Uploading'].includes(step);
    const isError =
      message.toLowerCase().includes('error') || message.includes('fail');

    if (!step && !message) return null;

    return (
      <div className="w-full p-4 bg-slate-100 dark:bg-slate-800 rounded-lg shadow-md flex flex-col space-y-2">
        <div className="flex items-center gap-2">
          {showSpinner && (
            <Loader2 className="h-4 w-4 animate-spin text-blue-600" />
          )}
          <p
            className={`text-sm font-medium ${
              isError ? 'text-red-600' : 'text-slate-800 dark:text-slate-100'
            }`}
          >
            {step || message}
          </p>
        </div>
        {!isError && step === 'Uploading' && (
          <>
            <Progress value={progress} className="h-2" />
            <p className="text-xs text-red-600 font-medium">
              ⚠️ Please do not close this page during upload!
            </p>
          </>
        )}
      </div>
    );
  }

  return (
    <div className="space-y-8">
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
        {/* File Upload Section */}
        <div className="space-y-6">
          <div>
            <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100 mb-4">
              Upload Files
            </h3>
            <div
              ref={dropRef}
              onDrop={handleDrop}
              onDragOver={(e) => {
                e.preventDefault();
                dropRef.current?.classList.add('border-blue-500');
              }}
              onDragLeave={() =>
                dropRef.current?.classList.remove('border-blue-500')
              }
              className="border-2 border-dashed rounded-xl p-8 text-center cursor-pointer transition-all"
            >
              <div className="flex flex-col items-center space-y-4">
                <div className="w-16 h-16 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-full flex items-center justify-center">
                  <Upload className="w-8 h-8 text-white" />
                </div>
                <div>
                  <p className="text-lg font-semibold text-slate-900 dark:text-slate-100">
                    Drag & drop files here
                  </p>
                  <p className="text-sm text-slate-500 dark:text-slate-400">
                    or click to select files (max 2GB)
                  </p>
                </div>
                <Button
                  variant="outline"
                  type="button"
                  onClick={triggerFileInput}
                >
                  Select Files
                </Button>

                <input
                  ref={fileInputRef}
                  id="file-upload"
                  type="file"
                  multiple
                  className="hidden"
                  onChange={handleFileChange}
                />
              </div>
            </div>

            {files.length > 0 && (
              <div className="space-y-4">
                <div className="flex items-center justify-between">
                  <h4 className="font-semibold text-slate-900 dark:text-slate-100">
                    Files ({files.length})
                  </h4>
                  <div className="text-sm text-slate-500 dark:text-slate-400">
                    <span>Total: {formatFileSize(totalSize)}</span>
                  </div>
                </div>
                <div className="space-y-3 max-h-64 overflow-y-auto">
                  {files.map((file, idx) => (
                    <Card
                      key={idx}
                      className="bg-white/60 dark:bg-slate-800/60 backdrop-blur-sm border-white/20 dark:border-slate-700/20"
                    >
                      <CardContent className="p-4">
                        <div className="flex items-center justify-between">
                          <div className="flex items-center space-x-3 flex-1 min-w-0">
                            <div className="w-10 h-10 bg-slate-100 dark:bg-slate-700 rounded-lg flex items-center justify-center">
                              <File className="w-5 h-5 text-slate-600 dark:text-slate-400" />
                            </div>
                            <div className="flex-1 min-w-0">
                              <p className="text-sm font-medium text-slate-900 dark:text-slate-100 truncate">
                                {file.name}
                              </p>
                              <p className="text-xs text-slate-500 dark:text-slate-400">
                                {formatFileSize(file.size)}
                              </p>
                            </div>
                          </div>
                          <div className="flex items-center space-x-2">
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => removeFile(idx)}
                              className="h-8 w-8 p-0"
                            >
                              <X className="w-4 h-4" />
                            </Button>
                          </div>
                        </div>
                      </CardContent>
                    </Card>
                  ))}

                  <div>
                    <Progress
                      value={
                        plan === 'free'
                          ? Math.min(
                              (totalSizeMB / PLAN_LIMITS.free.maxFileSizeMB) *
                                100,
                              100
                            )
                          : Math.min(
                              ((usedMB + totalSizeMB) /
                                PLAN_LIMITS[plan].maxMonthlyTransferSizeMB) *
                                100,
                              100
                            )
                      }
                      className={
                        isOverLimit ? 'progress-error' : 'progress-success'
                      }
                    />
                    <p
                      className={`text-xs mt-1 ${
                        isOverLimit
                          ? 'text-red-600 font-semibold'
                          : 'text-gray-600'
                      }`}
                    >
                      Plan: <strong>{plan}</strong> — Total:{' '}
                      {totalSizeMB.toFixed(2)} MB /{' '}
                      {plan === 'free'
                        ? `${PLAN_LIMITS.free.maxFileSizeMB} MB max per transfer`
                        : `${remainingMB.toFixed(2)} MB remaining this month`}
                    </p>
                  </div>
                </div>
              </div>
            )}
          </div>
        </div>
        {/* Transfer Details Section */}
        <div className="space-y-6">
          <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">
            Transfer Details
          </h3>

          <div className="space-y-4">
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="recipientEmail">Recipient Email *</Label>
                <Input
                  id="recipient"
                  type="email"
                  placeholder="recipient@example.com"
                  value={recipient}
                  onChange={(e) => setRecipient(e.target.value)}
                />
              </div>
            </div>
            <div className="space-y-2">
              <Label htmlFor="message">Message (Optional)</Label>
              <Textarea
                id="message"
                value={message}
                onChange={(e) => setMessage(e.target.value)}
                placeholder="Add a personal message..."
                rows={3}
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="message">Password *</Label>
              <Input
                id="password"
                type="password"
                placeholder="Enter a secure password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
              />
            </div>
          </div>
          <div className="bg-slate-50 dark:bg-slate-800/50 rounded-lg p-4">
            <h4 className="font-semibold text-slate-900 dark:text-slate-100 mb-2">
              Transfer Summary
            </h4>
            <div className="space-y-1 text-sm text-slate-600 dark:text-slate-400">
              <p>Total Size: {formatFileSize(totalSize)}</p>
              <p>Expires: 48 hours after sending</p>
              <p>Security: Password protected</p>
            </div>
          </div>
          <div className="bg-slate-50 dark:bg-slate-800/50 rounded-lg p-4">
            <UploadStatusToast
              step={uploadStep}
              progress={uploadProgress}
              message={uploadMessage}
            />
          </div>

          <Button
            onClick={handleSubmit}
            disabled={isOverLimit}
            className="w-full bg-gradient-to-r from-blue-500 to-indigo-600 hover:from-blue-600 hover:to-indigo-700"
            size="lg"
          >
            <>
              <Send className="w-4 h-4 mr-2" />
              Send Transfer
            </>
          </Button>
        </div>
      </div>
    </div>
  );
}
