/**
 * Share dialog for DMS files.
 * Allows sharing with users/groups and creating public share links.
 */

import React, { useState, useEffect, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Modal } from '@/components/ui/Modal';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { formatDateShort } from '@/utils/date';
import { Select } from '@/components/ui/Select';
import { Badge } from '@/components/ui/Badge';
import { EmptyState } from '@/components/ui/EmptyState';
import { useToast } from '@/components/ui/Toast';
import {
  shareFile,
  removeShare,
  type DmsFile,
  type DmsShare,
} from '@/api/dms';
import {
  fetchFilePermissions,
  grantPermission,
  revokePermission,
  createShareLink,
  revokeShareLink,
  type FilePermissionEntry,
  type ShareLinkEntry,
} from '@/api/permissions';

export interface ShareDialogProps {
  open: boolean;
  file: DmsFile | null;
  onClose: () => void;
  onShared: () => void;
}

export function ShareDialog({ open, file, onClose, onShared }: ShareDialogProps) {
  const { t } = useTranslation();
  const toast = useToast();
  const [shares, setShares] = useState<DmsShare[]>([]);
  const [permissions, setPermissions] = useState<FilePermissionEntry[]>([]);
  const [shareLinks, setShareLinks] = useState<ShareLinkEntry[]>([]);
  const [loading, setLoading] = useState(false);

  const [shareType, setShareType] = useState<'user' | 'group'>('user');
  const [sharePermission, setSharePermission] = useState<'read' | 'write'>('read');
  const [linkPassword, setLinkPassword] = useState('');
  const [linkExpiry, setLinkExpiry] = useState('');
  const [submitting, setSubmitting] = useState(false);

  // ── Share form (RHF + Zod) ──
  const shareSchema = z.object({
    shareId: z.string().min(1, 'required'),
  });
  type ShareFormData = z.infer<typeof shareSchema>;

  const { register: registerShare, handleSubmit: handleSubmitShare, reset: resetShare, formState: { errors: shareErrors } } = useForm<ShareFormData>({
    resolver: zodResolver(shareSchema),
    defaultValues: { shareId: '' },
  });

  const loadData = useCallback(async () => {
    if (!file) return;
    setLoading(true);
    try {
      const perms = await fetchFilePermissions(file.id);
      setPermissions(perms);
    } catch {
      setPermissions([]);
    }
    setLoading(false);
  }, [file]);

  useEffect(() => {
    if (open && file) {
      loadData();
    }
  }, [open, file, loadData]);

  const handleAddShare = useCallback(async (data: ShareFormData) => {
    if (!file) return;
    setSubmitting(true);
    try {
      const payload: { user_id?: string; group_id?: string; permission: 'read' | 'write' } = {
        permission: sharePermission,
      };
      if (shareType === 'user') payload.user_id = data.shareId;
      else payload.group_id = data.shareId;
      await shareFile(file.id, payload);
      toast.success(t('dms.shared'));
      resetShare({ shareId: '' });
      onShared();
      loadData();
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      toast.error(msg);
    }
    setSubmitting(false);
  }, [file, shareType, sharePermission, toast, t, onShared, loadData, resetShare]);

  const handleRemovePermission = useCallback(async (userId: string) => {
    if (!file) return;
    try {
      await revokePermission(file.id, userId);
      toast.success(t('permissions.revoked'));
      loadData();
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      toast.error(msg);
    }
  }, [file, toast, t, loadData]);

  const handleCreateLink = useCallback(async () => {
    if (!file) return;
    setSubmitting(true);
    try {
      const payload: { password?: string; expires_at?: string | null } = {};
      if (linkPassword) payload.password = linkPassword;
      if (linkExpiry) payload.expires_at = linkExpiry;
      const link = await createShareLink(file.id, payload);
      setShareLinks((prev) => [...prev, link]);
      toast.success(t('permissions.linkCreated'));
      setLinkPassword('');
      setLinkExpiry('');
      onShared();
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      toast.error(msg);
    }
    setSubmitting(false);
  }, [file, linkPassword, linkExpiry, toast, t, onShared]);

  const handleCopyLink = useCallback((url: string) => {
    navigator.clipboard.writeText(url).then(() => {
      toast.success(t('dms.linkCopied'));
    }).catch(() => {
      toast.error(t('dms.uploadError'));
    });
  }, [toast, t]);

  const handleRevokeLink = useCallback(async (linkId: string) => {
    try {
      await revokeShareLink(linkId);
      setShareLinks((prev) => prev.filter((l) => l.id !== linkId));
      toast.success(t('permissions.linkRevoked'));
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      toast.error(msg);
    }
  }, [toast, t]);

  if (!file) return null;

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={t('dms.shareWith')}
      size="lg"
      data-testid="share-dialog"
    >
      <div className="space-y-6">
        {/* Add share section */}
        <div className="space-y-3" data-testid="share-add-section">
          <h3 className="text-sm font-semibold text-secondary-900">{t('dms.addShare')}</h3>
          <form onSubmit={handleSubmitShare(handleAddShare)}>
          <div className="flex items-center gap-3 flex-wrap">
            <Select
              label={t('dms.userOrGroup')}
              options={[
                { value: 'user', label: t('permissions.user') },
                { value: 'group', label: t('permissions.group') },
              ]}
              value={shareType}
              onChange={(e) => setShareType(e.target.value as 'user' | 'group')}
            />
            <Input
              label={shareType === 'user' ? t('dms.userId') : t('dms.groupId')}
              {...registerShare('shareId')}
              error={shareErrors.shareId?.message === 'required' ? t('validation.required') : undefined}
              placeholder={shareType === 'user' ? t('dms.userId') : t('dms.groupId')}
            />
            <Select
              label={t('dms.permissionLevel')}
              options={[
                { value: 'read', label: t('permissions.permissionRead') },
                { value: 'write', label: t('permissions.permissionWrite') },
              ]}
              value={sharePermission}
              onChange={(e) => setSharePermission(e.target.value as 'read' | 'write')}
            />
          </div>
          <Button
            type="submit"
            isLoading={submitting}
            size="sm"
            className="mt-2"
          >
            {t('dms.addShare')}
          </Button>
          </form>
        </div>

        {/* Current permissions */}
        <div className="space-y-2" data-testid="share-permissions-list">
          <h3 className="text-sm font-semibold text-secondary-900">{t('permissions.filePermissions')}</h3>
          {loading ? (
            <p className="text-sm text-secondary-500">{t('dms.loading')}...</p>
          ) : permissions.length === 0 ? (
            <EmptyState title={t('permissions.noPermissions')} />
          ) : (
            <ul className="space-y-2" role="list">
              {permissions.map((perm) => (
                <li key={perm.id} className="flex items-center justify-between p-3 bg-secondary-50 rounded-md">
                  <div className="flex items-center gap-3">
                    <Badge variant={perm.permission === 'write' ? 'warning' : 'info'}>
                      {perm.permission === 'read' ? t('permissions.permissionRead') : t('permissions.permissionWrite')}
                    </Badge>
                    <span className="text-sm text-secondary-700">
                      {perm.user_name || perm.group_name || perm.user_id || perm.group_id}
                    </span>
                  </div>
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => perm.user_id && handleRemovePermission(perm.user_id)}
                  >
                    {t('dms.removeShare')}
                  </Button>
                </li>
              ))}
            </ul>
          )}
        </div>

        {/* Public share link section */}
        <div className="space-y-3 border-t border-secondary-200 pt-4" data-testid="share-link-section">
          <h3 className="text-sm font-semibold text-secondary-900">{t('dms.shareLink')}</h3>
          <div className="flex items-center gap-3 flex-wrap">
            <Input
              label={t('dms.password')}
              type="password"
              value={linkPassword}
              onChange={(e) => setLinkPassword(e.target.value)}
              placeholder={t('dms.password')}
            />
            <Input
              label={t('dms.expiryDate')}
              type="date"
              value={linkExpiry}
              onChange={(e) => setLinkExpiry(e.target.value)}
            />
          </div>
          <Button
            onClick={handleCreateLink}
            isLoading={submitting}
            size="sm"
          >
            {t('dms.createShareLink')}
          </Button>

          {shareLinks.length > 0 && (
            <ul className="space-y-2" role="list" data-testid="share-links-list">
              {shareLinks.map((link) => (
                <li key={link.id} className="flex items-center justify-between p-3 bg-secondary-50 rounded-md">
                  <div className="flex items-center gap-2 flex-1 min-w-0">
                    <span className="text-sm text-secondary-700 truncate">{link.url}</span>
                    {link.password_protected && (
                      <Badge variant="warning">{t('permissions.passwordProtected')}</Badge>
                    )}
                    {link.expires_at && (
                      <Badge variant="info">
                        {t('permissions.expiresAt')}: {formatDateShort(link.expires_at)}
                      </Badge>
                    )}
                  </div>
                  <div className="flex items-center gap-2 flex-shrink-0">
                    <Button
                      variant="secondary"
                      size="sm"
                      onClick={() => handleCopyLink(link.url)}
                    >
                      {t('dms.copyLink')}
                    </Button>
                    <Button
                      variant="danger"
                      size="sm"
                      onClick={() => handleRevokeLink(link.id)}
                    >
                      {t('dms.delete')}
                    </Button>
                  </div>
                </li>
              ))}
            </ul>
          )}
        </div>
      </div>
    </Modal>
  );
}
