/**
 * Report Sharing System
 * Share report configurations with team members and manage permissions
 */

export type PermissionLevel = 'view' | 'edit' | 'execute' | 'admin';

export interface ReportShare {
  id: string;
  reportId: string;
  sharedBy: string;
  sharedWith: string;
  permission: PermissionLevel;
  sharedAt: Date;
  expiresAt?: Date;
  notes?: string;
}

export interface SharePermissions {
  canView: boolean;
  canEdit: boolean;
  canExecute: boolean;
  canDelete: boolean;
  canShare: boolean;
}

export interface ReportShareStats {
  totalShares: number;
  sharedWith: number;
  permissions: Record<PermissionLevel, number>;
  activeShares: number;
  expiredShares: number;
}

/**
 * Permission matrix for different permission levels
 */
const permissionMatrix: Record<PermissionLevel, SharePermissions> = {
  view: {
    canView: true,
    canEdit: false,
    canExecute: false,
    canDelete: false,
    canShare: false,
  },
  edit: {
    canView: true,
    canEdit: true,
    canExecute: false,
    canDelete: false,
    canShare: false,
  },
  execute: {
    canView: true,
    canEdit: false,
    canExecute: true,
    canDelete: false,
    canShare: false,
  },
  admin: {
    canView: true,
    canEdit: true,
    canExecute: true,
    canDelete: true,
    canShare: true,
  },
};

/**
 * Create report share
 */
export function createReportShare(
  reportId: string,
  sharedBy: string,
  sharedWith: string,
  permission: PermissionLevel,
  expiresAt?: Date,
  notes?: string
): ReportShare {
  return {
    id: `SHARE-${Date.now()}`,
    reportId,
    sharedBy,
    sharedWith,
    permission,
    sharedAt: new Date(),
    expiresAt,
    notes,
  };
}

/**
 * Get permissions for a share
 */
export function getSharePermissions(permission: PermissionLevel): SharePermissions {
  return permissionMatrix[permission];
}

/**
 * Check if user has permission
 */
export function hasPermission(
  permission: PermissionLevel,
  action: keyof SharePermissions
): boolean {
  const permissions = getSharePermissions(permission);
  return permissions[action] || false;
}

/**
 * Validate permission level
 */
export function isValidPermissionLevel(permission: string): permission is PermissionLevel {
  return ['view', 'edit', 'execute', 'admin'].includes(permission);
}

/**
 * Check if share is expired
 */
export function isShareExpired(share: ReportShare): boolean {
  if (!share.expiresAt) return false;
  return new Date() > share.expiresAt;
}

/**
 * Get active shares
 */
export function getActiveShares(shares: ReportShare[]): ReportShare[] {
  return shares.filter(share => !isShareExpired(share));
}

/**
 * Get shares for report
 */
export function getSharesForReport(reportId: string, shares: ReportShare[]): ReportShare[] {
  return shares.filter(share => share.reportId === reportId && !isShareExpired(share));
}

/**
 * Get shares by user (shared with)
 */
export function getSharesByUser(userId: string, shares: ReportShare[]): ReportShare[] {
  return shares.filter(share => share.sharedWith === userId && !isShareExpired(share));
}

/**
 * Get shares created by user
 */
export function getSharesCreatedByUser(userId: string, shares: ReportShare[]): ReportShare[] {
  return shares.filter(share => share.sharedBy === userId && !isShareExpired(share));
}

/**
 * Update share permission
 */
export function updateSharePermission(
  share: ReportShare,
  newPermission: PermissionLevel
): ReportShare {
  return {
    ...share,
    permission: newPermission,
  };
}

/**
 * Revoke share
 */
export function revokeShare(share: ReportShare): ReportShare {
  return {
    ...share,
    expiresAt: new Date(),
  };
}

/**
 * Extend share expiration
 */
export function extendShareExpiration(share: ReportShare, days: number): ReportShare {
  const newExpiresAt = new Date();
  newExpiresAt.setDate(newExpiresAt.getDate() + days);

  return {
    ...share,
    expiresAt: newExpiresAt,
  };
}

/**
 * Get share statistics
 */
export function getShareStats(shares: ReportShare[]): ReportShareStats {
  const activeShares = getActiveShares(shares);
  const expiredShares = shares.filter(isShareExpired);

  const permissions: Record<PermissionLevel, number> = {
    view: 0,
    edit: 0,
    execute: 0,
    admin: 0,
  };

  activeShares.forEach(share => {
    permissions[share.permission]++;
  });

  const uniqueUsers = new Set(activeShares.map(s => s.sharedWith));

  return {
    totalShares: shares.length,
    sharedWith: uniqueUsers.size,
    permissions,
    activeShares: activeShares.length,
    expiredShares: expiredShares.length,
  };
}

/**
 * Get permission hierarchy
 */
export function getPermissionHierarchy(): Array<{
  level: PermissionLevel;
  name: string;
  description: string;
  permissions: string[];
}> {
  return [
    {
      level: 'view',
      name: 'Viewer',
      description: 'Can only view the report',
      permissions: ['View report configuration', 'View execution history'],
    },
    {
      level: 'edit',
      name: 'Editor',
      description: 'Can view and edit the report',
      permissions: [
        'View report configuration',
        'Edit report settings',
        'Modify recipients',
        'Change schedule',
      ],
    },
    {
      level: 'execute',
      name: 'Executor',
      description: 'Can view and execute the report',
      permissions: [
        'View report configuration',
        'Execute report immediately',
        'View execution history',
        'Download reports',
      ],
    },
    {
      level: 'admin',
      name: 'Administrator',
      description: 'Full control over the report',
      permissions: [
        'View report configuration',
        'Edit all settings',
        'Execute report',
        'Delete report',
        'Share with others',
        'Manage permissions',
      ],
    },
  ];
}

/**
 * Validate share request
 */
export function validateShareRequest(
  ownerPermission: PermissionLevel,
  requestedPermission: PermissionLevel
): { valid: boolean; reason?: string } {
  // Owner must have admin permission to share
  if (ownerPermission !== 'admin') {
    return {
      valid: false,
      reason: 'Only administrators can share reports',
    };
  }

  // Cannot share with higher permission than owner
  const permissionLevels: PermissionLevel[] = ['view', 'edit', 'execute', 'admin'];
  const ownerLevel = permissionLevels.indexOf(ownerPermission);
  const requestedLevel = permissionLevels.indexOf(requestedPermission);

  if (requestedLevel > ownerLevel) {
    return {
      valid: false,
      reason: 'Cannot share with higher permission level than your own',
    };
  }

  return { valid: true };
}

/**
 * Get share history
 */
export function getShareHistory(reportId: string, shares: ReportShare[]): ReportShare[] {
  return shares
    .filter(share => share.reportId === reportId)
    .sort((a, b) => b.sharedAt.getTime() - a.sharedAt.getTime());
}

/**
 * Get shares expiring soon
 */
export function getSharesExpiringSoon(shares: ReportShare[], daysThreshold: number = 7): ReportShare[] {
  const now = new Date();
  const threshold = new Date(now.getTime() + daysThreshold * 24 * 60 * 60 * 1000);

  return shares.filter(share => {
    if (!share.expiresAt || isShareExpired(share)) return false;
    return share.expiresAt <= threshold;
  });
}

/**
 * Bulk update permissions
 */
export function bulkUpdatePermissions(
  shares: ReportShare[],
  userIds: string[],
  newPermission: PermissionLevel
): ReportShare[] {
  return shares.map(share =>
    userIds.includes(share.sharedWith)
      ? updateSharePermission(share, newPermission)
      : share
  );
}

/**
 * Bulk revoke shares
 */
export function bulkRevokeShares(shares: ReportShare[], userIds: string[]): ReportShare[] {
  return shares.map(share =>
    userIds.includes(share.sharedWith) ? revokeShare(share) : share
  );
}

/**
 * Get share audit log
 */
export function getShareAuditLog(reportId: string, shares: ReportShare[]) {
  const reportShares = getShareHistory(reportId, shares);

  return {
    reportId,
    totalShares: reportShares.length,
    activeShares: getActiveShares(reportShares).length,
    auditLog: reportShares.map(share => ({
      id: share.id,
      action: 'shared',
      sharedBy: share.sharedBy,
      sharedWith: share.sharedWith,
      permission: share.permission,
      timestamp: share.sharedAt,
      status: isShareExpired(share) ? 'expired' : 'active',
    })),
  };
}

/**
 * Generate share link
 */
export function generateShareLink(share: ReportShare, baseUrl: string): string {
  const params = new URLSearchParams({
    shareId: share.id,
    reportId: share.reportId,
    permission: share.permission,
  });

  return `${baseUrl}/reports/shared?${params.toString()}`;
}

/**
 * Get share recommendations
 */
export function getShareRecommendations(reportId: string, teamSize: number) {
  return {
    reportId,
    recommendations: [
      {
        action: 'Share with Finance Team',
        permission: 'view',
        reason: 'Finance team needs visibility into payment reports',
      },
      {
        action: 'Share with Operations',
        permission: 'execute',
        reason: 'Operations can trigger reports as needed',
      },
      {
        action: 'Share with Management',
        permission: 'view',
        reason: 'Management needs access to executive summaries',
      },
    ],
  };
}
