# Microsoft 365 Integration - Complete Guide

## Description

This guide shows you how to configure and use Microsoft 365 (OneDrive/SharePoint) integration in your Laravel application, reusing the existing cloud storage architecture.

## Architecture

### ✅ **Reused Components**

The Microsoft integration completely reuses the existing architecture:

1. **`CloudStorageController`** - Unified controller (already existing)
2. **`CloudStorageService`** - Main service (already existing)
3. **`CloudServiceFactory`** - Factory pattern (already existing)
4. **`CloudStorageProvider`** - Interface (already existing)
5. **`CloudDocumentProvider`** - Interface (already existing)

### 🆕 **New Component**

- **`MicrosoftGraphProvider`** - Specific implementation for Microsoft Graph API

## Configuration

### 1. **Azure App Registration Configuration**

#### Step 1: Create App Registration
1. Go to [Azure Portal](https://portal.azure.com)
2. Navigate to "Azure Active Directory" > "App registrations"
3. Click on "New registration"
4. Complete the details:
   - **Name**: Your application name
   - **Supported account types**: Choose according to your needs
   - **Redirect URI**: Web - `https://your-domain.com/microsoft/callback`

#### Step 2: Configure API Permissions
1. Go to "API permissions"
2. Click on "Add a permission"
3. Select "Microsoft Graph"
4. Choose "Application permissions" (not Delegated)
5. Add the following permissions:
   - `Files.ReadWrite.All`
   - `Sites.ReadWrite.All`
   - `User.Read.All`

#### Step 3: Generate Client Secret
1. Go to "Certificates & secrets"
2. Click on "New client secret"
3. Add description and choose expiration
4. Copy the generated value

#### Step 4: Get IDs
1. Copy the "Application (client) ID" from the Overview page
2. Copy the "Directory (tenant) ID" from the Overview page

### 2. **Create JSON Configuration File**

Create a JSON file with the following structure:

```json
{
    "client_id": "your-application-client-id-here",
    "client_secret": "your-client-secret-here",
    "tenant_id": "your-tenant-id-here",
    "organization_domain": "your-organization-domain.com",
    "graph_endpoint": "https://graph.microsoft.com/v1.0",
    "auth_endpoint": "https://login.microsoftonline.com",
    "scopes": [
        "https://graph.microsoft.com/.default"
    ]
}
```

**Required fields:**
- `client_id`: Application ID from Azure AD
- `client_secret`: Generated Client Secret
- `tenant_id`: Directory ID from Azure AD
- `organization_domain`: Your organization domain

**Optional fields:**
- `graph_endpoint`: Microsoft Graph endpoint (default: v1.0)
- `auth_endpoint`: Authentication endpoint (default: login.microsoftonline.com)
- `scopes`: Permission scopes (default: .default)

### 3. **Configure in the Application**

Go to `/setup/cloud-storage` and configure Microsoft 365 with:
- **Organization Domain**: Your organization domain
- **Microsoft Configuration File**: The JSON file you created

## Usage

### 🔄 **Total Architecture Reuse**

Once configured, you can use Microsoft 365 exactly the same as Google Workspace:

#### Upload Files
```php
// The same code works for both providers
$storageService = new CloudStorageService(
    new CloudServiceFactory(),
    $config // Can be Google or Microsoft
);

$fileId = $storageService->uploadFile('documents/report.pdf', $fileContents);
```

#### Create Documents
```php
// Create Word document
$documentId = $storageService->createDocument('My Document');

// Create Excel spreadsheet
$spreadsheetId = $storageService->createSpreadsheet('My Spreadsheet');
```

#### List Files
```php
$files = $storageService->listFiles('/');
```

### 🎯 **Provider Selection**

In views, you can select the provider:

```php
// In the controller
$selectedProvider = $request->input('provider'); // 'google' or 'microsoft'

$cloudConfig = CloudServiceConfiguration::where('provider', $selectedProvider)->first();
```

```html
<!-- In the view -->
<select name="provider" id="provider">
    <option value="google">Google Workspace</option>
    <option value="microsoft">Microsoft 365</option>
</select>
```

### 📁 **Available Operations**

| Operation | Google | Microsoft | Code |
|-----------|--------|-----------|--------|
| Upload file | ✅ | ✅ | `uploadFile()` |
| Download file | ✅ | ✅ | `downloadFile()` |
| Delete file | ✅ | ✅ | `deleteFile()` |
| Get URL | ✅ | ✅ | `getFileUrl()` |
| Create folder | ✅ | ✅ | `createFolder()` |
| List files | ✅ | ✅ | `listFiles()` |
| Create document | ✅ | ✅ | `createDocument()` |
| Create spreadsheet | ✅ | ✅ | `createSpreadsheet()` |
| Get edit URL | ✅ | ✅ | `getDocumentEditUrl()` |
| Share file | ✅ | ✅ | `shareFile()` |
| Configure permissions | ✅ | ✅ | `configureFilePermissions()` |

## Technical Differences

### 🔐 **Authentication**

| Aspect | Google | Microsoft |
|---------|--------|-----------|
| **Method** | Service Account | Client Credentials |
| **Scope** | `https://www.googleapis.com/auth/drive` | `https://graph.microsoft.com/.default` |
| **Token** | JWT | OAuth 2.0 Client Credentials |
| **Configuration** | Service Account JSON | Azure AD App JSON |

### 📄 **Document Types**

| Type | Google | Microsoft |
|------|--------|-----------|
| **Documents** | Google Docs | Word (.docx) |
| **Spreadsheets** | Google Sheets | Excel (.xlsx) |
| **Edit URL** | `docs.google.com` | `word.office.com` |

### 🗂️ **Storage**

| Aspect | Google | Microsoft |
|---------|--------|-----------|
| **Service** | Google Drive | OneDrive for Business |
| **API** | Google Drive API | Microsoft Graph API |
| **Endpoint** | `https://www.googleapis.com/` | `https://graph.microsoft.com/v1.0/` |

## Testing

### 🧪 **Test Command**

Run the test command to verify the integration:

```bash
php artisan test:microsoft-integration
```

This command:
1. Verifies configuration
2. Lists files
3. Creates a test folder
4. Creates a test document
5. Gets the edit URL
6. Cleans up test files

### 🔍 **Logs**

All operations are automatically logged:

```php
Log::info('Document created via cloud service', [
    'document_id' => $document->id,
    'document_provider_id' => $documentId,
    'type' => 'document',
    'user_id' => auth()->id(),
    'provider' => $config->provider->value, // 'microsoft'
]);
```

## Troubleshooting

### ❌ **Common Errors**

#### 1. "Invalid JSON format" error
- Verify that the JSON file is valid
- Make sure all required fields are present
- Use an online JSON validator to check the format

#### 2. "Missing Client ID" error
- Verify that `client_id` is in the JSON file
- Make sure it's the correct Application ID from Azure AD

#### 3. "Invalid Client Secret" error
- Verify that `client_secret` has at least 32 characters
- Make sure it hasn't expired in Azure AD

#### 4. "Invalid Tenant ID" error
- Verify that `tenant_id` is the correct Directory ID
- Make sure the format is a valid GUID

#### 5. "Invalid organization domain" error
- Verify that the domain is valid
- Make sure it matches the domain configured in Azure AD

### 🔧 **Debug Mode**

Enable debug logging:

```env
LOG_LEVEL=debug
```

### 📊 **Monitoring**

You can monitor operations in:
- **Logs**: `storage/logs/laravel.log`
- **Telescope**: If enabled
- **Horizon**: For queued operations

## Architecture Advantages

### ✅ **Benefits**

1. **Total Reuse**: No code duplication
2. **Consistency**: Same behavior for both providers
3. **Maintainability**: Single place for updates
4. **Scalability**: Easy to add new providers
5. **Testing**: Same tests for both providers
6. **Multi-tenant**: Configuration per tenant with JSON files

### 🚀 **Next Steps**

1. **Configure Azure App Registration**
2. **Create JSON configuration file**
3. **Test the integration** with `php artisan test:microsoft-integration`
4. **Use in production** by selecting Microsoft as provider
5. **Monitor logs** to verify functionality

## Usage Examples

### 📝 **Create Document with Microsoft**

```php
// The same code works for both providers
$config = CloudServiceConfiguration::where('provider', 'microsoft')->first();
$storageService = new CloudStorageService(new CloudServiceFactory(), $config);

$documentId = $storageService->createDocument('My Word Document');
$editUrl = $storageService->getDocumentEditUrl($documentId, 'document');

// $editUrl will be: https://word.office.com/we/wordeditorframe.aspx?...
```

### 📊 **Create Spreadsheet with Microsoft**

```php
$spreadsheetId = $storageService->createSpreadsheet('My Excel Sheet');
$editUrl = $storageService->getDocumentEditUrl($spreadsheetId, 'spreadsheet');

// $editUrl will be: https://excel.office.com/we/exceleditorframe.aspx?...
```

### 📁 **Upload File to OneDrive**

```php
$fileId = $storageService->uploadFile('documents/report.pdf', $fileContents);
$fileUrl = $storageService->getFileUrl($fileId);

// $fileUrl will be: https://graph.microsoft.com/v1.0/me/drive/items/{fileId}
```

## JSON Configuration File

### 📋 **Complete Structure**

```json
{
    "client_id": "00000000-0000-0000-0000-000000000000",
    "client_secret": "your-very-long-client-secret-here",
    "tenant_id": "00000000-0000-0000-0000-000000000000",
    "organization_domain": "your-company.com",
    "graph_endpoint": "https://graph.microsoft.com/v1.0",
    "auth_endpoint": "https://login.microsoftonline.com",
    "scopes": [
        "https://graph.microsoft.com/.default"
    ],
    "additional_settings": {
        "timeout": 30,
        "retry_attempts": 3
    }
}
```

### 🔒 **Security**

- The JSON file is stored encrypted in the database
- Sensitive fields (`client_secret`) are protected
- Validation ensures all required fields are present
- GUID format is validated for `client_id` and `tenant_id`

The Microsoft 365 integration is ready and completely reuses your existing architecture!
