import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
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 { Select } from '@/components/ui/select';
import { ConfirmationDialog } from '@/components/ui/confirmation-dialog';
import {
  Share2,
  Copy,
  Check,
  Trash2,
  Plus,
  ExternalLink,
  Calendar,
  Eye,
  Loader2,
} from 'lucide-react';
import { useToast } from '@/hooks/useToast';
import { formatDistanceToNow, format } from 'date-fns';
import { fr } from 'date-fns/locale';
import { cn } from '@/lib/utils';

/**
 * FE-COMP-013: Share link generation and management UI component
 */

export interface ShareLink {
  id: string;
  share_token: string;
  expires_at?: string;
  access_count?: number;
  created_at: string;
  permissions?: string;
}

export interface ShareLinkManagerProps {
  resourceId: string;
  resourceType: 'track' | 'playlist';
  onCreateShare: (
    resourceId: string,
    options: CreateShareOptions,
  ) => Promise<ShareLink>;
  onRevokeShare?: (shareId: string) => Promise<void>;
  getShareUrl: (token: string) => string;
  className?: string;
}

export interface CreateShareOptions {
  expires_in_days?: number;
  is_public?: boolean;
  permissions?: string;
}

/**
 * Share link manager component for creating and managing share links
 */
export function ShareLinkManager({
  resourceId,
  resourceType,
  onCreateShare,
  onRevokeShare,
  getShareUrl,
  className,
}: ShareLinkManagerProps) {
  const { success: showSuccess, error: showError } = useToast();
  const queryClient = useQueryClient();
  const [isCreating, setIsCreating] = useState(false);
  const [showCreateForm, setShowCreateForm] = useState(false);
  const [expiresIn, setExpiresIn] = useState<number>(7);
  const [isPublic, setIsPublic] = useState(true);
  const [shareLinks, setShareLinks] = useState<ShareLink[]>([]);
  const [copiedToken, setCopiedToken] = useState<string | null>(null);
  const [shareToRevoke, setShareToRevoke] = useState<string | null>(null);

  // Create share mutation
  // Action 4.4.1.5: Add optimistic update
  const createShareMutation = useMutation({
    mutationFn: (options: CreateShareOptions) =>
      onCreateShare(resourceId, options),
    onMutate: async (options: CreateShareOptions) => {
      // Cancel outgoing refetches
      await queryClient.cancelQueries({
        queryKey: [`${resourceType}ShareLinks`, resourceId],
      });

      // Snapshot previous value
      const previousShareLinks = [...shareLinks];

      // Optimistically add share link to local state
      const optimisticShare: ShareLink = {
        id: `temp-${Date.now()}`,
        share_token: `temp-token-${Date.now()}`,
        expires_at: options.expires_in_days
          ? new Date(
              Date.now() + options.expires_in_days * 24 * 60 * 60 * 1000,
            ).toISOString()
          : undefined,
        access_count: 0,
        created_at: new Date().toISOString(),
        permissions: options.permissions,
      };
      setShareLinks((prev) => [optimisticShare, ...prev]);

      return { previousShareLinks };
    },
    onError: (error: any, _options, context) => {
      // Rollback on error
      if (context?.previousShareLinks) {
        setShareLinks(context.previousShareLinks);
      }
      showError(error.message || 'Erreur lors de la création du lien');
    },
    onSuccess: (newShare) => {
      // Replace optimistic share with real one
      setShareLinks((prev) =>
        prev.map((s) => (s.id.startsWith('temp-') ? newShare : s)),
      );
      setShowCreateForm(false);
      showSuccess('Lien de partage créé avec succès');
      queryClient.invalidateQueries({
        queryKey: [`${resourceType}ShareLinks`, resourceId],
      });
    },
  });

  // Revoke share mutation
  // Action 4.4.1.5: Add optimistic update
  const revokeShareMutation = useMutation({
    mutationFn: (shareId: string) => {
      if (onRevokeShare) {
        return onRevokeShare(shareId);
      }
      throw new Error('Revoke function not provided');
    },
    onMutate: async (shareId: string) => {
      // Cancel outgoing refetches
      await queryClient.cancelQueries({
        queryKey: [`${resourceType}ShareLinks`, resourceId],
      });

      // Snapshot previous value
      const previousShareLinks = [...shareLinks];

      // Optimistically remove share link from local state
      setShareLinks((prev) => prev.filter((s) => s.id !== shareId));

      return { previousShareLinks };
    },
    onError: (error: any, _shareId, context) => {
      // Rollback on error
      if (context?.previousShareLinks) {
        setShareLinks(context.previousShareLinks);
      }
      showError(error.message || 'Erreur lors de la révocation');
    },
    onSuccess: () => {
      if (shareToRevoke) {
        setShareToRevoke(null);
        showSuccess('Lien de partage révoqué');
        queryClient.invalidateQueries({
          queryKey: [`${resourceType}ShareLinks`, resourceId],
        });
      }
    },
  });

  const handleCreateShare = async () => {
    setIsCreating(true);
    try {
      await createShareMutation.mutateAsync({
        expires_in_days: expiresIn,
        is_public: isPublic,
      });
    } finally {
      setIsCreating(false);
    }
  };

  const handleCopy = async (token: string) => {
    const shareUrl = getShareUrl(token);
    try {
      await navigator.clipboard.writeText(shareUrl);
      setCopiedToken(token);
      showSuccess('Lien copié dans le presse-papiers');
      setTimeout(() => setCopiedToken(null), 2000);
    } catch (err) {
      showError('Erreur lors de la copie');
    }
  };

  const handleRevoke = (shareId: string) => {
    setShareToRevoke(shareId);
  };

  const confirmRevoke = () => {
    if (shareToRevoke) {
      revokeShareMutation.mutate(shareToRevoke);
    }
  };

  const isExpired = (expiresAt?: string) => {
    if (!expiresAt) return false;
    return new Date(expiresAt) < new Date();
  };

  return (
    <Card className={className}>
      <CardHeader>
        <div className="flex items-center justify-between">
          <CardTitle className="flex items-center gap-2">
            <Share2 className="h-5 w-5" />
            Liens de partage
          </CardTitle>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setShowCreateForm(!showCreateForm)}
          >
            <Plus className="h-4 w-4 mr-2" />
            Créer un lien
          </Button>
        </div>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* Create Form */}
        {showCreateForm && (
          <div className="p-4 border rounded-lg space-y-4 bg-muted/50">
            <div className="space-y-2">
              <Label>Expiration (jours)</Label>
              <Select
                value={expiresIn.toString()}
                onChange={(value) => setExpiresIn(Number(value))}
                options={[
                  { value: '1', label: '1 jour' },
                  { value: '7', label: '7 jours' },
                  { value: '30', label: '30 jours' },
                  { value: '90', label: '90 jours' },
                  { value: '365', label: '1 an' },
                  { value: '0', label: 'Jamais' },
                ]}
              />
            </div>
            <div className="flex items-center gap-2">
              <input
                type="checkbox"
                id="isPublic"
                checked={isPublic}
                onChange={(e) => setIsPublic(e.target.checked)}
                className="rounded"
              />
              <Label htmlFor="isPublic" className="cursor-pointer">
                Lien public (accessible sans authentification)
              </Label>
            </div>
            <div className="flex gap-2">
              <Button
                onClick={handleCreateShare}
                disabled={isCreating || createShareMutation.isPending}
                className="flex-1"
              >
                {isCreating || createShareMutation.isPending ? (
                  <>
                    <Loader2 className="h-4 w-4 mr-2 animate-spin" />
                    Création...
                  </>
                ) : (
                  <>
                    <Share2 className="h-4 w-4 mr-2" />
                    Créer le lien
                  </>
                )}
              </Button>
              <Button
                variant="outline"
                onClick={() => setShowCreateForm(false)}
                disabled={isCreating || createShareMutation.isPending}
              >
                Annuler
              </Button>
            </div>
          </div>
        )}

        {/* Share Links List */}
        {shareLinks.length === 0 && !showCreateForm ? (
          <div className="text-center py-8 text-muted-foreground">
            <Share2 className="h-12 w-12 mx-auto mb-4 opacity-50" />
            <p>Aucun lien de partage créé</p>
            <p className="text-sm mt-2">
              Créez un lien pour partager ce{' '}
              {resourceType === 'track' ? 'morceau' : 'playlist'}
            </p>
          </div>
        ) : (
          <div className="space-y-3">
            {shareLinks.map((share) => {
              const shareUrl = getShareUrl(share.share_token);
              const expired = isExpired(share.expires_at);
              const isCopied = copiedToken === share.share_token;

              return (
                <div
                  key={share.id}
                  className={cn(
                    'p-4 border rounded-lg space-y-3',
                    expired && 'opacity-60 bg-muted/30',
                  )}
                >
                  <div className="flex items-start justify-between gap-4">
                    <div className="flex-1 min-w-0 space-y-2">
                      <div className="flex items-center gap-2">
                        <Input
                          value={shareUrl}
                          readOnly
                          className="flex-1 font-mono text-sm"
                        />
                        <Button
                          variant="outline"
                          size="icon"
                          onClick={() => handleCopy(share.share_token)}
                        >
                          {isCopied ? (
                            <Check className="h-4 w-4 text-green-600" />
                          ) : (
                            <Copy className="h-4 w-4" />
                          )}
                        </Button>
                        <Button
                          variant="outline"
                          size="icon"
                          onClick={() => window.open(shareUrl, '_blank')}
                          title="Ouvrir le lien"
                        >
                          <ExternalLink className="h-4 w-4" />
                        </Button>
                      </div>
                      <div className="flex flex-wrap items-center gap-4 text-xs text-muted-foreground">
                        {share.expires_at && (
                          <div className="flex items-center gap-1">
                            <Calendar className="h-3 w-3" />
                            {expired ? (
                              <span className="text-destructive">
                                Expiré le{' '}
                                {format(
                                  new Date(share.expires_at),
                                  'dd/MM/yyyy',
                                  { locale: fr },
                                )}
                              </span>
                            ) : (
                              <span>
                                Expire{' '}
                                {formatDistanceToNow(
                                  new Date(share.expires_at),
                                  { addSuffix: true, locale: fr },
                                )}
                              </span>
                            )}
                          </div>
                        )}
                        {share.access_count !== undefined && (
                          <div className="flex items-center gap-1">
                            <Eye className="h-3 w-3" />
                            <span>{share.access_count} accès</span>
                          </div>
                        )}
                        <div className="text-xs">
                          Créé{' '}
                          {formatDistanceToNow(new Date(share.created_at), {
                            addSuffix: true,
                            locale: fr,
                          })}
                        </div>
                      </div>
                    </div>
                    {onRevokeShare && (
                      <Button
                        variant="ghost"
                        size="icon"
                        onClick={() => handleRevoke(share.id)}
                        className="text-destructive hover:text-destructive"
                        title="Révoquer le lien"
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </CardContent>

      {/* Revoke Confirmation Dialog */}
      {onRevokeShare && (
        <ConfirmationDialog
          open={!!shareToRevoke}
          onClose={() => setShareToRevoke(null)}
          onConfirm={confirmRevoke}
          title="Révoquer le lien de partage"
          description="Êtes-vous sûr de vouloir révoquer ce lien ? Il ne sera plus accessible."
          confirmLabel="Révoquer"
          cancelLabel="Annuler"
          variant="destructive"
        />
      )}
    </Card>
  );
}
