"use client";

import { useEffect, useState, useCallback, useMemo } from "react";
import { useAuth } from "@/contexts/AuthContext";
import { useApi } from "@/hooks/use-api";
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";
import { Badge } from "@/components/ui/badge";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "@/components/ui/select";
import { RefreshCw, Inbox, Folder, Download, Play, Pause, Loader2, PhoneIncoming, PhoneCall, Trash2 } from "lucide-react";
import { format } from "date-fns";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle
} from "@/components/ui/alert-dialog";

const FOLDERS = ['INBOX', 'Family', 'Friends', 'Old', 'Work', 'Urgent'];
const FRIENDLY_FOLDER = (f) => (f === 'INBOX' ? 'New' : f);

function formatDuration(sec) {
  if (isNaN(sec)) return '0:00';
  const m = Math.floor(sec / 60);
  const s = Math.floor(sec % 60).toString().padStart(2, '0');
  return `${m}:${s}`;
}

function formatBytes(bytes) {
  if (!bytes && bytes !== 0) return '—';
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
}

function formatVoicemailDate(dateStr) {
    try {
        return format(new Date(dateStr), "MMM d, yyyy 'at' h:mm a");
    } catch {
        return dateStr;
    }
}

export function VoicemailPanel({ extensionId: extProp }) {
  const { token } = useAuth();
  const apiFetch = useApi();
  const [extensionId, setExtensionId] = useState(extProp || null);
  const [loadingExt, setLoadingExt] = useState(!extProp);
  const [loading, setLoading] = useState(true);
  const [voicemails, setVoicemails] = useState([]);
  const [activeFolder, setActiveFolder] = useState('INBOX');
  const [search, setSearch] = useState('');
  const [expandedId, setExpandedId] = useState(null);
  const [audioMap, setAudioMap] = useState({}); // messageId -> { url, loading, error }
  const [movingId, setMovingId] = useState(null);
  const [refreshing, setRefreshing] = useState(false);
  const [vmToDelete, setVmToDelete] = useState(null);

  useEffect(() => {
    if (extProp || !token) return;
    const load = async () => {
      setLoadingExt(true);
      try {
        const res = await apiFetch(`${process.env.NEXT_PUBLIC_API_URL}/extensions/me`);
        if (res.ok) {
          const data = await res.json();
          setExtensionId(data.extensionId);
        }
      } catch (e) {
        if (e.message !== 'Unauthorized') {
          // silent
        }
      } finally {
        setLoadingExt(false);
      }
    };
    load();
  }, [token, extProp, apiFetch]);

  const fetchVoicemails = useCallback(async () => {
    if (!token || !extensionId) return;
    setRefreshing(true);
    if (voicemails.length === 0) setLoading(true);
    try {
      const res = await apiFetch(`${process.env.NEXT_PUBLIC_API_URL}/extensions/${extensionId}/voicemails`);
      if (res.ok) {
        const data = await res.json();
        setVoicemails(Array.isArray(data) ? data : []);
      } else {
        setVoicemails([]);
      }
    } catch (e) {
      if (e.message !== 'Unauthorized') {
        setVoicemails([]);
      }
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  }, [token, extensionId, voicemails.length, apiFetch]);

  useEffect(() => {
    if (extensionId) fetchVoicemails();
  }, [extensionId, fetchVoicemails]);

  const filtered = useMemo(() => {
    return voicemails
      .filter(v => v.folder === activeFolder)
      .filter(v => {
        if (!search) return true;
        const t = search.toLowerCase();
        return (
          v.callerIdName?.toLowerCase().includes(t) ||
          v.callerIdNum?.toLowerCase().includes(t) ||
          v.messageId?.toLowerCase().includes(t)
        );
      })
      .sort((a, b) => new Date(b.date) - new Date(a.date));
  }, [voicemails, activeFolder, search]);

  const toggleExpand = async (vm) => {
    const isOpening = expandedId !== vm.messageId;
    setExpandedId(isOpening ? vm.messageId : null);
    if (isOpening && vm.hasAudio && !audioMap[vm.messageId]?.url) {
      setAudioMap(m => ({ ...m, [vm.messageId]: { url: null, loading: true } }));
      try {
        const res = await apiFetch(`${process.env.NEXT_PUBLIC_API_URL}/extensions/${extensionId}/voicemails/${vm.messageId}/download`);
        if (!res.ok) throw new Error('Download failed');
        const blob = await res.blob();
        const url = URL.createObjectURL(blob);
        setAudioMap(m => ({ ...m, [vm.messageId]: { url, loading: false } }));
      } catch(e) {
        if (e.message !== 'Unauthorized') {
          setAudioMap(m => ({ ...m, [vm.messageId]: { url: null, loading: false, error: true } }));
        }
      }
    }
  };

  const moveVoicemail = async (vm, target) => {
    if (target === vm.folder) return;
    setMovingId(vm.messageId);
    try {
      await apiFetch(`${process.env.NEXT_PUBLIC_API_URL}/extensions/${extensionId}/voicemails/${vm.messageId}/move`, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ targetFolder: target })
      });
      setVoicemails(list => list.map(x => x.messageId === vm.messageId ? { ...x, folder: target } : x));
      if (target !== activeFolder) {
        setExpandedId(null);
      }
    } catch(e) {
      if (e.message !== 'Unauthorized') {
        // silent fail
      }
    } finally {
      setMovingId(null);
    }
  };

  const downloadVoicemail = async (vm) => {
    if (!vm.hasAudio) return;
    try {
      const res = await apiFetch(`${process.env.NEXT_PUBLIC_API_URL}/extensions/${extensionId}/voicemails/${vm.messageId}/download`);
      if (!res.ok) return;
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${vm.messageId}.wav`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
    } catch(e) {
      if (e.message !== 'Unauthorized') {
        // ignore
      }
    }
  };

  const handleDelete = async () => {
    if (!vmToDelete || !token || !extensionId) return;
    try {
      const res = await apiFetch(`${process.env.NEXT_PUBLIC_API_URL}/extensions/${extensionId}/voicemails/${vmToDelete.messageId}`, {
        method: 'DELETE',
      });
      if (res.ok) {
        setVoicemails(list => list.filter(v => v.messageId !== vmToDelete.messageId));
        if (expandedId === vmToDelete.messageId) setExpandedId(null);
      }
    } catch(e) {
      if (e.message !== 'Unauthorized') {
        // silent
      }
    } finally {
      setVmToDelete(null);
    }
  };

  const loadingState = loading || loadingExt;

  return (
    <>
      <Card className="bg-gray-950/50 border-gray-800">
        <CardHeader className="gap-2">
          <div className="flex items-center justify-between flex-wrap gap-3">
            <div>
              <CardTitle>Voicemail (VVM)</CardTitle>
              <CardDescription>
                {extensionId ? `Extension ${extensionId} visual voicemail` : 'Loading extension...'}
              </CardDescription>
            </div>
            <div className="flex items-center gap-2">
              <Button
                size="icon"
                variant="outline"
                onClick={fetchVoicemails}
                disabled={loadingState || refreshing || !extensionId}
              >
                <RefreshCw className={`h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />
              </Button>
            </div>
          </div>
          <div className="flex flex-wrap gap-2 mt-2">
            {FOLDERS.map(folder => {
              const count = voicemails.filter(v => v.folder === folder).length;
              const active = folder === activeFolder;
              return (
                <Button
                  key={folder}
                  variant={active ? 'secondary' : 'ghost'}
                  size="sm"
                  onClick={() => { setActiveFolder(folder); setExpandedId(null); }}
                  className="flex items-center gap-2"
                >
                  {folder === 'INBOX' ? <Inbox className="h-3.5 w-3.5" /> : <Folder className="h-3.5 w-3.5" />}
                  <span>{FRIENDLY_FOLDER(folder)}</span>
                  <Badge variant="outline" className="text-[10px] px-1 py-0 leading-none border-gray-600">
                    {count}
                  </Badge>
                </Button>
              );
            })}
          </div>
          <div className="w-full">
            <Input
              placeholder="Search caller, number or ID..."
              value={search}
              onChange={e => setSearch(e.target.value)}
              className="bg-gray-900 border-gray-700"
              disabled={loadingState}
            />
          </div>
        </CardHeader>
        <CardContent className="pt-0">
          {loadingState ? (
            <div className="space-y-3">
              {[...Array(5)].map((_, i) => (
                <Skeleton key={i} className="h-16 w-full" />
              ))}
            </div>
          ) : filtered.length === 0 ? (
            <div className="text-center py-12 text-gray-500">
              No voicemails in {FRIENDLY_FOLDER(activeFolder)}{search && ' matching your search'}.
            </div>
          ) : (
            <div className="divide-y divide-gray-800">
              {filtered.map(vm => {
                const expanded = expandedId === vm.messageId;
                const audioInfo = audioMap[vm.messageId];
                return (
                  <div key={vm.messageId} className="py-3">
                    <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:gap-4">
                      <button
                        onClick={() => toggleExpand(vm)}
                        className="flex-1 text-left group focus:outline-none"
                      >
                        <div className="flex flex-wrap items-center justify-between gap-3">
                          {/* Caller block */}
                          <div className="flex items-center gap-3 min-w-0">
                            <div className="p-2 rounded-md bg-gray-800 group-hover:bg-gray-700 transition-colors">
                              {vm.callerIdNum ? <PhoneIncoming className="h-4 w-4 text-blue-400" /> : <PhoneCall className="h-4 w-4 text-blue-400" />}
                            </div>
                            <div className="min-w-0">
                              <div className="font-medium text-white truncate">
                                {vm.callerIdName || 'Unknown Caller'}
                              </div>
                              <div className="text-xs text-gray-400 font-mono truncate">
                                {vm.callerIdNum || 'No Number'}
                              </div>
                            </div>
                          </div>
                          {/* Meta (desktop) */}
                          <div className="hidden sm:flex items-center gap-6 text-xs sm:text-sm">
                            <div className="text-gray-300">{formatDuration(vm.duration)}</div>
                            <div className="text-gray-400 hidden md:block">{formatBytes(vm.fileSize)}</div>
                            <div className="text-gray-500 hidden lg:block truncate max-w-[180px]">
                              {formatVoicemailDate(vm.date)}
                            </div>
                          </div>
                          {/* Meta (mobile compact) */}
                          <div className="flex sm:hidden w-full justify-start gap-4 text-[11px] text-gray-400">
                            <span>{formatDuration(vm.duration)}</span>
                            <span>{formatBytes(vm.fileSize)}</span>
                            <span className="truncate">{formatVoicemailDate(vm.date)}</span>
                          </div>
                        </div>
                      </button>
                      {/* Actions */}
                      <div className="flex flex-wrap items-center gap-2">
                        <Button
                          size="icon"
                          variant="ghost"
                          onClick={() => toggleExpand(vm)}
                          title="Play"
                          disabled={!vm.hasAudio}
                          className="h-8 w-8"
                        >
                          {expanded && audioInfo?.url
                            ? <Pause className="h-4 w-4" />
                            : <Play className="h-4 w-4" />}
                        </Button>
                        <Button
                          size="icon"
                          variant="ghost"
                          onClick={() => downloadVoicemail(vm)}
                          disabled={!vm.hasAudio}
                          className="h-8 w-8"
                        >
                          <Download className="h-4 w-4" />
                        </Button>
                        <Select
                          onValueChange={(val) => moveVoicemail(vm, val)}
                          disabled={movingId === vm.messageId}
                        >
                          <SelectTrigger className="w-[78px] h-8 bg-gray-900 border-gray-700 text-xs">
                            <SelectValue placeholder="Move" />
                          </SelectTrigger>
                          <SelectContent>
                            {FOLDERS.filter(f => f !== vm.folder).map(f => (
                              <SelectItem key={f} value={f} className="text-xs">
                                {FRIENDLY_FOLDER(f)}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                        <Button
                          size="icon"
                          variant="ghost"
                          onClick={() => setVmToDelete(vm)}
                          className="h-8 w-8 text-red-500/80 hover:text-red-500 hover:bg-red-900/20"
                          title="Delete"
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                        {movingId === vm.messageId && (
                          <Loader2 className="h-4 w-4 animate-spin text-gray-400" />
                        )}
                      </div>
                    </div>
                    {expanded && (
                      <div className="mt-3 pl-0 sm:pl-14 space-y-3">
                        {/* Audio / status */}
                        {vm.hasAudio ? (
                          audioInfo?.loading ? (
                            <div className="text-sm text-gray-400 flex items-center gap-2">
                              <Loader2 className="h-4 w-4 animate-spin" />
                              Loading audio...
                            </div>
                          ) : audioInfo?.error ? (
                            <div className="text-sm text-red-400">
                              Failed to load audio.
                            </div>
                          ) : audioInfo?.url ? (
                            <audio
                              controls
                              autoPlay
                              src={audioInfo.url}
                              className="w-full"
                            />
                          ) : null
                        ) : (
                          <div className="text-sm text-gray-500">
                            No audio available for this voicemail.
                          </div>
                        )}
                        {/* Detail chips */}
                        <div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-gray-400">
                          <span>ID: {vm.messageId}</span>
                          <span>Orig: {vm.originalMessageId}</span>
                          <span>Folder: {FRIENDLY_FOLDER(vm.folder)}</span>
                          <span className="sm:hidden">Size: {formatBytes(vm.fileSize)}</span>
                          <span className="md:hidden">At: {formatVoicemailDate(vm.date)}</span>
                        </div>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          )}
        </CardContent>
      </Card>
      <AlertDialog open={!!vmToDelete} onOpenChange={(open) => !open && setVmToDelete(null)}>
        <AlertDialogContent className="bg-gray-950 border-gray-800 text-white">
          <AlertDialogHeader>
            <AlertDialogTitle>Delete voicemail?</AlertDialogTitle>
            <AlertDialogDescription className="text-gray-400">
              This permanently deletes the voicemail from{' '}
              <span className="text-white font-medium">
                {vmToDelete?.callerIdName || 'Unknown Caller'}
              </span>{' '}
              ({vmToDelete?.callerIdNum || 'No Number'}). This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel className="border-gray-700 hover:bg-gray-800">
              Cancel
            </AlertDialogCancel>
              <AlertDialogAction
                onClick={handleDelete}
                className="bg-red-600 hover:bg-red-700 text-white"
              >
                Delete
              </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
}

export default VoicemailPanel;
