'use client';

import React, { useEffect, useState, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '@/store/store';
import {
  HardDrive,
  FileText,
  Download,
  Trash2,
  Loader2,
  FolderOpen,
  CheckSquare,
  Square,
  Layers,
  AlertTriangle,
  RefreshCw,
} from 'lucide-react';
import { Card } from '@/components/shared/Card';
import { StatusBadge } from '@/components/shared/StatusBadge';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { getHeader } from '@/app/(presentation-generator)/services/api/header';
import { toast } from 'sonner';
import { HamsterLoader } from '@/components/ui/hamster-loader';

interface StorageSummary {
  total_presentations: number;
  total_files: number;
  total_size_bytes: number;
  total_deleted: number;
  total_master_decks: number;
  master_deck_files: number;
  master_deck_size_bytes: number;
}

interface StoragePresentation {
  id: string;
  title: string | null;
  status: string;
  created_at: string | null;
  file_count: number;
  total_size_bytes: number;
  has_export: boolean;
}

interface ClientOption {
  id: string;
  name: string;
}

function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
}


export default function StoragePage() {
  const user = useSelector((state: RootState) => state.auth.user);
  const isSuperAdmin = user?.role === 'super_admin';
  const defaultClientId = user?.clientId || undefined;

  const [selectedClientId, setSelectedClientId] = useState<string | undefined>(
    isSuperAdmin ? undefined : defaultClientId
  );
  const [clients, setClients] = useState<ClientOption[]>([]);
  const [summary, setSummary] = useState<StorageSummary | null>(null);
  const [presentations, setPresentations] = useState<StoragePresentation[]>([]);
  const [loading, setLoading] = useState(true);
  const [deleteTarget, setDeleteTarget] = useState<StoragePresentation | null>(null);
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [bulkDeleteOpen, setBulkDeleteOpen] = useState(false);
  const [purging, setPurging] = useState(false);

  // Load client list for super_admin
  useEffect(() => {
    if (isSuperAdmin) {
      fetch('/api/v1/admin/clients', { headers: getHeader() })
        .then((r) => (r.ok ? r.json() : []))
        .then((data) => setClients(data))
        .catch(() => {});
    }
  }, [isSuperAdmin]);

  const load = useCallback(async () => {
    setLoading(true);
    setSelectedIds(new Set());
    try {
      const params = selectedClientId ? `?client_id=${selectedClientId}` : '';
      const headers = getHeader();
      const [summaryRes, presRes] = await Promise.all([
        fetch(`/api/v1/admin/storage/summary${params}`, { headers }),
        fetch(`/api/v1/admin/storage/presentations${params}`, { headers }),
      ]);
      if (summaryRes.ok) setSummary(await summaryRes.json());
      if (presRes.ok) setPresentations(await presRes.json());
    } catch (e) {
      console.error('Storage load error:', e);
    } finally {
      setLoading(false);
    }
  }, [selectedClientId]);

  useEffect(() => {
    load();
  }, [load]);

  const handleDownload = (id: string) => {
    window.open(`/api/v1/admin/storage/presentations/${id}/download`, '_blank');
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    try {
      const res = await fetch(`/api/v1/admin/storage/presentations/${deleteTarget.id}`, {
        method: 'DELETE',
        headers: getHeader(),
      });
      if (res.ok) {
        toast.success('Presentation deleted');
        setDeleteTarget(null);
        load();
      } else {
        toast.error('Failed to delete');
      }
    } catch {
      toast.error('Failed to delete');
    }
  };

  const handleBulkDelete = async () => {
    try {
      const res = await fetch('/api/v1/admin/storage/presentations/bulk-delete', {
        method: 'POST',
        headers: { ...getHeader(), 'Content-Type': 'application/json' },
        body: JSON.stringify({ ids: Array.from(selectedIds) }),
      });
      if (res.ok) {
        const data = await res.json();
        toast.success(`Deleted ${data.deleted_count} presentations`);
        setBulkDeleteOpen(false);
        load();
      } else {
        toast.error('Bulk delete failed');
      }
    } catch {
      toast.error('Bulk delete failed');
    }
  };

  const handlePurge = async () => {
    setPurging(true);
    try {
      const params = selectedClientId ? `?client_id=${selectedClientId}` : '';
      const res = await fetch(`/api/v1/admin/storage/purge${params}`, {
        method: 'POST',
        headers: getHeader(),
      });
      if (res.ok) {
        const data = await res.json();
        const totalFiles = (data.purged_files || 0) + (data.purged_images || 0);
        toast.success(
          `Purged ${totalFiles} files (${formatBytes(data.purged_bytes || 0)})`
        );
        load();
      } else {
        const err = await res.json().catch(() => ({}));
        toast.error(err.detail || 'Purge failed');
      }
    } catch {
      toast.error('Purge failed');
    } finally {
      setPurging(false);
    }
  };

  const toggleSelect = (id: string) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (selectedIds.size === presentations.length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(presentations.map((p) => p.id)));
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center h-64">
        <HamsterLoader size="md" />
      </div>
    );
  }

  return (
    <div className="space-y-6 animate-fadeIn">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-semibold">Storage</h1>
        <div className="flex items-center gap-3">
          {/* Client selector for super_admin */}
          {isSuperAdmin && clients.length > 0 && (
            <Select
              value={selectedClientId || '__all__'}
              onValueChange={(v) => setSelectedClientId(v === '__all__' ? undefined : v)}
            >
              <SelectTrigger className="w-[200px]">
                <SelectValue placeholder="All clients" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="__all__">All clients</SelectItem>
                {clients.map((c) => (
                  <SelectItem key={c.id} value={c.id}>
                    {c.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}
          <Button variant="outline" size="sm" onClick={load}>
            <RefreshCw className="w-4 h-4 mr-1" />
            Refresh
          </Button>
        </div>
      </div>

      {/* Summary Cards */}
      {summary && (
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 animate-fadeIn">
          <Card className="p-5">
            <div className="flex items-start justify-between">
              <div>
                <p className="text-sm text-muted-foreground">Presentations</p>
                <p className="text-2xl font-bold mt-1">{summary.total_presentations}</p>
              </div>
              <div className="p-2 rounded-lg bg-[hsl(var(--primary-light))] text-[hsl(var(--primary))]">
                <FileText className="w-5 h-5" />
              </div>
            </div>
          </Card>
          <Card className="p-5">
            <div className="flex items-start justify-between">
              <div>
                <p className="text-sm text-muted-foreground">Export Files</p>
                <p className="text-2xl font-bold mt-1">{summary.total_files}</p>
              </div>
              <div className="p-2 rounded-lg bg-[hsl(var(--primary-light))] text-[hsl(var(--primary))]">
                <FolderOpen className="w-5 h-5" />
              </div>
            </div>
          </Card>
          <Card className="p-5">
            <div className="flex items-start justify-between">
              <div>
                <p className="text-sm text-muted-foreground">Master Decks</p>
                <p className="text-2xl font-bold mt-1">
                  {summary.total_master_decks}
                  <span className="text-sm font-normal text-muted-foreground ml-1">
                    ({summary.master_deck_files} files)
                  </span>
                </p>
              </div>
              <div className="p-2 rounded-lg bg-[hsl(var(--primary-light))] text-[hsl(var(--primary))]">
                <Layers className="w-5 h-5" />
              </div>
            </div>
          </Card>
          <Card className="p-5">
            <div className="flex items-start justify-between">
              <div>
                <p className="text-sm text-muted-foreground">Total Size</p>
                <p className="text-2xl font-bold mt-1">
                  {formatBytes(summary.total_size_bytes + (summary.master_deck_size_bytes || 0))}
                </p>
              </div>
              <div className="p-2 rounded-lg bg-[hsl(var(--success)/0.1)] text-[hsl(var(--success))]">
                <HardDrive className="w-5 h-5" />
              </div>
            </div>
          </Card>
        </div>
      )}

      {/* Soft-deleted notice + purge */}
      {summary && summary.total_deleted > 0 && isSuperAdmin && (
        <div className="flex items-center justify-between p-3 bg-[hsl(var(--warning)/0.08)] border border-[hsl(var(--warning)/0.3)] rounded-lg">
          <div className="flex items-center gap-2 text-sm text-[hsl(var(--warning))]">
            <AlertTriangle className="w-4 h-4" />
            <span>{summary.total_deleted} soft-deleted presentation(s) with files still on disk.</span>
          </div>
          <Button
            variant="outline"
            size="sm"
            onClick={handlePurge}
            disabled={purging}
            className="text-[hsl(var(--warning))] border-[hsl(var(--warning)/0.3)] hover:bg-[hsl(var(--warning)/0.08)]"
          >
            {purging ? <Loader2 className="w-3.5 h-3.5 mr-1 animate-spin" /> : <Trash2 className="w-3.5 h-3.5 mr-1" />}
            Purge Files
          </Button>
        </div>
      )}

      {/* Bulk actions toolbar */}
      {selectedIds.size > 0 && (
        <div className="flex items-center gap-3 p-3 bg-[hsl(var(--primary)/0.06)] border border-[hsl(var(--primary)/0.2)] rounded-lg">
          <span className="text-sm text-[hsl(var(--primary))] font-medium">
            {selectedIds.size} selected
          </span>
          <Button
            variant="destructive"
            size="sm"
            onClick={() => setBulkDeleteOpen(true)}
          >
            <Trash2 className="w-3.5 h-3.5 mr-1" />
            Delete Selected
          </Button>
          <Button
            variant="ghost"
            size="sm"
            onClick={() => setSelectedIds(new Set())}
          >
            Clear
          </Button>
        </div>
      )}

      {/* Presentations Table */}
      <Card>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b bg-[hsl(var(--surface))]">
                <th className="p-3 w-10">
                  <button onClick={toggleSelectAll} className="text-muted-foreground hover:text-foreground">
                    {selectedIds.size === presentations.length && presentations.length > 0 ? (
                      <CheckSquare className="w-4 h-4" />
                    ) : (
                      <Square className="w-4 h-4" />
                    )}
                  </button>
                </th>
                <th className="text-left p-3 font-medium text-muted-foreground">Title</th>
                <th className="text-left p-3 font-medium text-muted-foreground">Status</th>
                <th className="text-left p-3 font-medium text-muted-foreground">Created</th>
                <th className="text-right p-3 font-medium text-muted-foreground">Files</th>
                <th className="text-right p-3 font-medium text-muted-foreground">Size</th>
                <th className="text-right p-3 font-medium text-muted-foreground">Actions</th>
              </tr>
            </thead>
            <tbody>
              {presentations.length === 0 ? (
                <tr>
                  <td colSpan={7} className="p-8 text-center text-muted-foreground">
                    No presentations found.
                  </td>
                </tr>
              ) : (
                presentations.map((p) => (
                  <tr
                    key={p.id}
                    className={`border-b last:border-0 hover:bg-[hsl(var(--surface))] ${selectedIds.has(p.id) ? 'bg-[hsl(var(--primary)/0.05)]' : ''}`}
                  >
                    <td className="p-3">
                      <button onClick={() => toggleSelect(p.id)} className="text-muted-foreground hover:text-foreground">
                        {selectedIds.has(p.id) ? (
                          <CheckSquare className="w-4 h-4 text-[hsl(var(--primary))]" />
                        ) : (
                          <Square className="w-4 h-4" />
                        )}
                      </button>
                    </td>
                    <td className="p-3">
                      <span className="font-medium">{p.title || 'Untitled'}</span>
                    </td>
                    <td className="p-3">
                      <StatusBadge status={p.status as 'draft' | 'in_review' | 'approved'} />
                    </td>
                    <td className="p-3 text-muted-foreground">
                      {p.created_at ? new Date(p.created_at).toLocaleDateString() : '—'}
                    </td>
                    <td className="p-3 text-right text-muted-foreground">{p.file_count}</td>
                    <td className="p-3 text-right text-muted-foreground">
                      {p.total_size_bytes > 0 ? formatBytes(p.total_size_bytes) : '—'}
                    </td>
                    <td className="p-3 text-right">
                      <div className="flex items-center justify-end gap-1">
                        {p.has_export && (
                          <Button
                            variant="ghost"
                            size="sm"
                            onClick={() => handleDownload(p.id)}
                            title="Download PPTX"
                          >
                            <Download className="w-4 h-4" />
                          </Button>
                        )}
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => setDeleteTarget(p)}
                          title="Delete"
                        >
                          <Trash2 className="w-4 h-4 text-[hsl(var(--error))]" />
                        </Button>
                      </div>
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </Card>

      {/* Delete Confirmation */}
      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Delete Presentation</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground">
            Are you sure you want to delete &quot;{deleteTarget?.title || 'Untitled'}&quot;?
            Associated files will be cleaned up by the retention service.
          </p>
          <div className="flex justify-end gap-2 mt-4">
            <Button variant="outline" onClick={() => setDeleteTarget(null)}>
              Cancel
            </Button>
            <Button variant="destructive" onClick={handleDelete}>
              Delete
            </Button>
          </div>
        </DialogContent>
      </Dialog>

      {/* Bulk Delete Confirmation */}
      <Dialog open={bulkDeleteOpen} onOpenChange={(open) => !open && setBulkDeleteOpen(false)}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Delete {selectedIds.size} Presentations</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground">
            Are you sure you want to delete {selectedIds.size} selected presentations?
            This action can be undone by an admin.
          </p>
          <div className="flex justify-end gap-2 mt-4">
            <Button variant="outline" onClick={() => setBulkDeleteOpen(false)}>
              Cancel
            </Button>
            <Button variant="destructive" onClick={handleBulkDelete}>
              Delete All
            </Button>
          </div>
        </DialogContent>
      </Dialog>
    </div>
  );
}
