# FC Mobile License System - All User Flows & Experiences

## 🎯 User Experience Flows

### 1. **First Time User - No License**
**What happens:**
- App starts → License check → API returns 404 "Plugin not installed or no license found"
- **User sees:** `no_license` message popup
- **User action:** Clicks "Close" → App logs out → Returns to server selection

### 2. **Valid Free Trial - Fresh License**
**What happens:**
- App starts → API returns valid free trial (expires in 5 days)
- **User sees:** Normal app usage, no popups
- **Background:** App sets next check in 7 days

### 3. **Valid Premium - Fresh License**
**What happens:**
- App starts → API returns valid premium (expires in 30 days)
- **User sees:** Normal app usage, no popups
- **Background:** App sets next check in 7 days

### 4. **Lifetime License**
**What happens:**
- App starts → API returns lifetime license
- **User sees:** Normal app usage forever, no popups
- **Background:** App checks every 7 days for updates only

### 5. **Free Trial - Expiring Soon (1+ days left)**
**What happens:**
- App starts → License valid but expires in any number of days (e.g., 1, 3, 10, 30 days)
- **User sees:** Normal app usage, no popups
- **Note:** Free trial users don't see any kind of warning until license actually expires

### 6. **Premium - Expiring Soon (1-7 days left) - Admin User**
**What happens:**
- App starts → License valid but expires in 1-7 days (e.g., 1, 3, 5, 7 days)
- **Admin sees:** `license_expiring_admin` message popup every 8 hours
- **User action:** Clicks "Close" → App continues normally
- **Background:** Popup won't show again for 8 hours
- **Note:** Warning starts when ≤7 days left, continues until expiry

### 7. **Premium - Expiring Soon (1-7 days left) - Regular User**
**What happens:**
- App starts → License valid but expires in 1-7 days (e.g., 1, 3, 5, 7 days)
- **User sees:** Normal app usage, no popups
- **Note:** Only admins get expiring warnings for premium, regular users see nothing

### 8. **Free Trial - Expired 1-7 Days Ago - Grace Period**
**What happens:**
- App starts → License expired 1-7 days ago (e.g., 1, 2, 5, 7 days ago)
- **User sees:** `free_trial_grace_user` message popup every 8 hours
- **Admin sees:** `free_trial_grace_admin` message popup every 8 hours
- **User action:** Clicks "Close" → App continues normally
- **Background:** Still in 7-day grace period

### 9. **Premium - Expired 1-7 Days Ago - Grace Period**
**What happens:**
- App starts → License expired 1-7 days ago (e.g., 1, 2, 5, 7 days ago)
- **User sees:** `license_expired_grace_user` message popup every 8 hours
- **Admin sees:** `license_expired_grace_admin` message popup every 8 hours
- **User action:** Clicks "Close" → App continues normally
- **Background:** Still in 7-day grace period

### 10. **Free Trial - Expired 8+ Days Ago - Blocked**
**What happens:**
- App starts → License expired 8+ days ago (past grace period)
- **User sees:** `free_trial_ended_user` message popup
- **Admin sees:** `free_trial_ended_admin` message popup
- **User action:** Clicks "Close" → App logs out → Returns to server selection
- **Result:** App is completely blocked

### 11. **Premium - Expired 8+ Days Ago - Blocked**
**What happens:**
- App starts → License expired 8+ days ago (past grace period)
- **User sees:** `license_expired_final_user` message popup
- **Admin sees:** `license_expired_final_admin` message popup
- **User action:** Clicks "Close" → App logs out → Returns to server selection
- **Result:** App is completely blocked

### 12. **Network Error (User-Side) - Has Valid Local License**
**What happens:**
- App starts → API call fails (no internet, poor connection, DNS issues)
- App checks local database → Finds valid license (expires in 5 days)
- **User sees:** `network_error` message popup
- **User action:** Fix network connection and retry
- **Background:** App uses local license data as fallback

### 13. **Server Error (Server-Side) - Has Valid Local License**
**What happens:**
- App starts → API call fails (server down, 500 error, maintenance)
- App checks local database → Finds valid license (expires in 5 days)
- **User sees:** `server_error` message popup (brief notification)
- **User action:** Nothing required, server issue will be resolved
- **Background:** App uses local license data as fallback

### 14. **Network Error (User-Side) - Has Expired Local License (Grace Period)**
**What happens:**
- App starts → API call fails (no internet, poor connection, DNS issues)
- App checks local database → Finds expired license (expired 3 days ago)
- **User sees:** `network_error` message popup + grace period popup every 8 hours
- **User action:** Fix network connection for future license updates
- **Background:** App applies grace period logic using local data

### 15. **Server Error (Server-Side) - Has Expired Local License (Grace Period)**
**What happens:**
- App starts → API call fails (server down, 500 error, maintenance)
- App checks local database → Finds expired license (expired 3 days ago)
- **User sees:** `server_error` message popup + grace period popup every 8 hours
- **User action:** Nothing required, server issue will be resolved
- **Background:** App applies grace period logic using local data

### 14. **API Server Down - Has Expired Local License (Past Grace Period)**
**What happens:**
- App starts → API call fails (network error)
- App checks local database → Finds expired license (expired 10 days ago)
- **User sees:** "No license" popup → App logs out
- **Result:** App is blocked

### 15. **API Server Down - No Local License**
**What happens:**
- App starts → API call fails (network error)
- App checks local database → No license found
- **User sees:** "No license" popup → App logs out
- **Result:** App is blocked

### 16. **API Returns 404 - No License Found - Has Local License in Grace**
**What happens:**
- App starts → API returns 404 "Plugin not installed or no license found"
- App checks local database → Finds license expired 2 days ago
- **User sees:** Grace period popup every 8 hours
- **Background:** App ignores API error, uses local grace period logic

### 17. **Popup Timing - Multiple App Opens**
**What happens:**
- User sees grace period popup → Clicks "Close"
- User closes app and reopens 2 hours later
- **User sees:** No popup (8-hour timer still active)
- User reopens 9 hours later
- **User sees:** Popup appears again

### 18. **License Renewal During Grace Period**
**What happens:**
- User in grace period (seeing popups every 8 hours)
- Admin renews license on server
- Next time app checks (up to 7-10 days later)
- **User sees:** Popups stop, normal app usage resumes

### 19. **Date Parsing Error**
**What happens:**
- App receives malformed expiry date from API
- **User sees:** App treats license as expired → Shows appropriate popup
- **Background:** Error handling prevents app crash

### 20. **Missing Popup Message**
**What happens:**
- API doesn't include expected popup message type
- **User sees:** Default fallback message instead of custom message
- **Background:** App doesn't crash, shows generic message

## 🔄 State Transitions

### License Status Progression
```
No License → Valid License → Expiring Soon → Expired (Grace) → Blocked
```

### User Experience Progression
```
Normal Use → Warnings → Grace Period Popups → App Blocked
```

## ⏰ Timing Behaviors

### Popup Frequency
- **Grace Period Popups:** Every 8 hours
- **Expiring Warnings:** Every 8 hours (admin only)
- **License Checks:** Every 7 days (both free and premium)

### Grace Period Duration
- **Free Trial:** 7 days after expiration
- **Premium:** 7 days after expiration
- **Lifetime:** Never expires

## 👥 User Role Differences

### Admin Users
- Get expiring license warnings (premium only)
- See renewal instructions and portal links
- Get more detailed error messages

### Regular Users
- No expiring warnings (premium)
- Get instructions to contact admin
- See simplified error messages

## 🚫 App Blocking Scenarios

### Immediate Blocking (No Grace Period)
1. No license found anywhere (API + local)
2. License expired >7 days ago
3. Invalid license data

### Graceful Blocking (With Warnings)
1. License expired 1-7 days ago (grace period)
2. License expiring soon (admin warnings only)

## 📱 User Actions & Outcomes

### When User Sees Popup
- **Clicks "Close":** App continues (if in grace period) or logs out (if blocked)
- **Popup appears again:** After 8 hours (if still in grace period)

### When App is Blocked
- **User logged out automatically**
- **SharedPreferences cleared**
- **Navigated back to server selection**
- **Must re-authenticate to continue**

## 🔧 Background Behaviors

### Automatic License Checks
- **App Start**: Triggered during initial navigation
- **User Login**: Fresh check after successful authentication (bypasses previous states)
- **Scheduled Intervals**: Based on license type (every 7 days for both free and premium)
- **Network Recovery**: Automatic retry with user-friendly error dialogs
- **Fallback**: Uses local data when API is unavailable

### Data Persistence
- License data saved to local database
- Popup timing stored in SharedPreferences
- Server details updated with license info

### Error Recovery
- API failures → Check local license
- Date parsing errors → Treat as expired
- Missing messages → Use fallback text

## 📝 Message Key Reference

### Popup Message Types & Content

| Message Key | User Type | Scenario | Message Content |
|-------------|-----------|----------|-----------------|
| `no_license` | All | No valid license found | "You do not have a valid licence. Please provide a valid licence key" |
| `free_trial_grace_admin` | Admin | Free trial in grace period | "Your Free Trial will end soon. You can get the full version of Fluent Community Mobile App here." |
| `free_trial_grace_user` | User | Free trial in grace period | "The Free Trial period of this app will end soon. Please contact your community admin for mobile app access continuity." |
| `free_trial_ended_admin` | Admin | Free trial expired (blocked) | "Your Free Trial has ended. You can get the full version of Fluent Community Mobile App here." |
| `free_trial_ended_user` | User | Free trial expired (blocked) | "The Free Trial period of this app has ended. Please contact your community admin for mobile app access." |
| `license_expiring_admin` | Admin | Premium expiring soon | "Your License for Fluent Community Mobile is expiring soon. Please extend your license from LazyCoders customer portal" |
| `license_expired_grace_admin` | Admin | Premium in grace period | "Your License for Fluent Community Mobile has expired. Please extend your license from LazyCoders customer portal" |
| `license_expired_grace_user` | User | Premium in grace period | "License has expired for this community. App access will be revoked soon. Please contact your community admin." |
| `license_expired_final_admin` | Admin | Premium expired (blocked) | "Your License for Fluent Community Mobile has expired. Please extend your license from LazyCoders customer portal" |
| `license_expired_final_user` | User | Premium expired (blocked) | "Access restricted due to expired license. Please contact your community admin." |
| `network_error` | All | Network connectivity issues | "Network connection failed. Please check your internet connection and try again." |
| `server_error` | All | Server-side issues | "License server is temporarily unavailable. Please try again later or contact support if the issue persists." |

## 🧪 **Actual API Response Examples**

### **1. No License Found (404)**
```json
{
    "status": 404,
    "message": "Plugin not installed or no license found.",
    "license_type": "invalid",
    "data": [],
    "popup_message": [/* all 10 message types */]
}
```
**App Logic:** Show `no_license` popup → Logout → Return to server selection

### **2. Free Trial Valid - Not Expired**
```json
{
    "status": 200,
    "message": "Your free trial license is valid.",
    "license_type": "free_trial",
    "data": {
        "status": "valid",
        "expiration_date": "2025-09-15 09:54:45" // Future date
    },
    "popup_message": [/* all 10 message types */]
}
```
**App Logic:** Normal usage (no popups)

### **3. Free Trial Valid - But Expired (Grace Period)**
```json
{
    "status": 200,
    "message": "Your free trial license is valid.",
    "license_type": "free_trial",
    "data": {
        "status": "valid",
        "expiration_date": "2025-09-05 09:54:45" // 3 days ago
    },
    "popup_message": [/* all 10 message types */]
}
```
**App Logic:** Check days since expiration → Show grace period popups every 8 hours

### **4. Free Trial Expired - Past Grace Period**
```json
{
    "status": 200,
    "message": "Your free trial has expired. Please purchase a paid license.",
    "license_type": "free_trial",
    "data": {
        "status": "expired",
        "expiration_date": "2025-08-24 09:54:45" // 15+ days ago
    },
    "popup_message": [/* all 10 message types */]
}
```
**App Logic:** Block app completely

### **5. Premium Valid - Not Expiring Soon**
```json
{
    "status": 200,
    "message": "Your premium license key is valid.",
    "license_type": "premium",
    "data": {
        "status": "valid",
        "expiration_date": "2025-09-25 09:33:58", // 17+ days away
        "variation_title": "Paid"
    },
    "popup_message": [/* all 10 message types */]
}
```
**App Logic:** Normal usage (no popups)

### **6. Premium Valid - Expiring Soon (Admin Warnings)**
```json
{
    "status": 200,
    "message": "Your premium license key is valid.",
    "license_type": "premium",
    "data": {
        "status": "valid",
        "expiration_date": "2025-09-09 09:33:58", // 1 day away
        "variation_title": "Paid"
    },
    "popup_message": [/* all 10 message types */]
}
```
**App Logic:** Normal usage + Admin warnings every 8 hours (if user is admin)

### **7. Premium Valid - But Expired (Grace Period)**
```json
{
    "status": 200,
    "message": "Your premium license key is valid.",
    "license_type": "premium",
    "data": {
        "status": "valid",
        "expiration_date": "2025-09-02 09:33:58", // 6 days ago
        "variation_title": "Paid"
    },
    "popup_message": [/* all 10 message types */]
}
```
**App Logic:** Check days since expiration → Show grace period popups every 8 hours

### **8. Premium Expired - Past Grace Period**
```json
{
    "status": 200,
    "message": "Your Premium License is expire, please renew again.",
    "license_type": "premium",
    "data": {
        "status": "expired",
        "expiration_date": "2025-08-20 09:33:58", // 19+ days ago
        "variation_title": "Paid"
    },
    "popup_message": [/* all 10 message types */]
}
```
**App Logic:** Block app completely

## 🔑 **Key App Logic Rules:**

1. **Always use `expiration_date`** for all date calculations
2. **Ignore `data.status`** - server keeps it "valid" during grace period
3. **App calculates grace period:** 7 days from `expiration_date`
4. **Server never blocks:** Always returns 200 for existing licenses

## 🔐 **Login-Triggered License Check:**

### **Implementation:**
- **Location:** `LoginController.loginOnTap()` method
- **Timing:** After successful authentication and app config loading
- **Purpose:** Fresh license validation with current user permissions

### **Flow:**
```
User Login → Authentication → App Config → License Check → Navigation
                                              ↓
                                    (Network error handling)
                                              ↓
                                    (License popups if needed)
                                              ↓
                                    (Continue to app)
```

### **Benefits:**
- **Fresh Validation:** Bypasses any previous "no check" states
- **User-Specific:** Uses current user's admin permissions for popup selection
- **Network Resilient:** Includes robust network error handling with retry dialogs
- **Security:** Ensures license compliance on every new session
5. **404 only for:** Non-existent licenses
