import express from 'express';
import path from 'path';
import { db } from './server/db.js';
import { createServer as createViteServer } from 'vite';

const app = express();
const PORT = 3000;

app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb', extended: true }));

// Helper to parse cookies from requests
const getCookies = (req: express.Request): Record<string, string> => {
  const list: Record<string, string> = {};
  const cookieHeader = req.headers.cookie;
  if (!cookieHeader) return list;
  cookieHeader.split(';').forEach((cookie: string) => {
    const parts = cookie.split('=');
    const name = parts[0].trim();
    if (!name) return;
    const value = parts.slice(1).join('=').trim();
    list[name] = decodeURIComponent(value);
  });
  return list;
};

// Middleware to resolve logged-in user
const authMiddleware = (req: express.Request, res: express.Response, next: express.NextFunction) => {
  const cookies = getCookies(req);
  const userId = cookies['user_session_id'];
  if (userId) {
    const user = db.getUser(userId);
    if (user) {
      (req as any).user = user;
    }
  }
  next();
};

app.use(authMiddleware);

// Middleware to restrict access to Admins only
const requireAdmin = (req: express.Request, res: express.Response, next: express.NextFunction) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized: Session missing' });
  }
  const isAdmin = currentUser.role === 'Admin' || currentUser.designation === 'Marketplace Admin' || currentUser.designation === 'Sub Admin' || (currentUser.designation && currentUser.designation.toLowerCase().includes('admin')) || currentUser.email.toLowerCase().includes('admin');
  if (!isAdmin) {
    return res.status(403).json({ error: 'Forbidden: Admin access required' });
  }
  next();
};

// --- AUTHENTICATION ENDPOINTS ---

// Google Login simulated page
app.get('/auth/google-simulate', (req, res) => {
  const userEmail = req.query.email || 'abuturab1746@gmail.com';
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Sign in with Google</title>
      <script src="https://cdn.tailwindcss.com"></script>
      <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">
      <style>
        body {
          font-family: 'Roboto', sans-serif;
          background-color: #f0f4f9;
        }
      </style>
    </head>
    <body class="flex items-center justify-center min-h-screen">
      <div class="bg-white border border-gray-200 rounded-lg p-10 max-w-md w-full shadow-md text-center">
        <!-- Google Logo SVG -->
        <div class="flex justify-center mb-6">
          <svg class="w-12 h-12" viewBox="0 0 24 24">
            <path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
            <path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
            <path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.06H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.94l2.85-2.22-.04-.63z"/>
            <path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.06l3.66 2.84c.87-2.6 3.3-4.52 6.16-4.52z"/>
          </svg>
        </div>

        <h1 class="text-2xl font-normal text-[#1f1f1f] mb-2">Sign in with Google</h1>
        <p class="text-[#474747] text-sm mb-8">to continue to B2B Garments Marketplace</p>

        <!-- Profile accounts list -->
        <div class="space-y-3 mb-8">
          <button onclick="selectAccount('${userEmail}', 'Abu Turab', 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=100&q=80')" 
            class="w-full flex items-center justify-between p-3 rounded-lg border border-gray-200 hover:bg-gray-50 transition cursor-pointer text-left">
            <div class="flex items-center space-x-3">
              <img src="https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=100&q=80" class="w-10 h-10 rounded-full border" alt="Avatar">
              <div>
                <p class="font-medium text-sm text-[#1f1f1f]">Abu Turab</p>
                <p class="text-xs text-[#5f6368]">${userEmail}</p>
              </div>
            </div>
            <span class="text-xs bg-blue-50 text-blue-600 px-2 py-1 rounded">Owner/Admin</span>
          </button>

          <button onclick="selectAccount('garment.pro@supplier.com', 'Rahman Chowdhury', 'https://images.unsplash.com/photo-1560250097-0b93528c311a?w=100&q=80')" 
            class="w-full flex items-center justify-between p-3 rounded-lg border border-gray-200 hover:bg-gray-50 transition cursor-pointer text-left">
            <div class="flex items-center space-x-3">
              <img src="https://images.unsplash.com/photo-1560250097-0b93528c311a?w=100&q=80" class="w-10 h-10 rounded-full border" alt="Avatar">
              <div>
                <p class="font-medium text-sm text-[#1f1f1f]">Rahman Chowdhury</p>
                <p class="text-xs text-[#5f6368]">garment.pro@supplier.com</p>
              </div>
            </div>
            <span class="text-xs bg-emerald-50 text-emerald-600 px-2 py-1 rounded">Supplier</span>
          </button>

          <!-- Custom Account Input -->
          <div class="pt-4 border-t border-gray-100 text-left">
            <label class="block text-xs font-medium text-gray-500 mb-2">Or log in with another email:</label>
            <div class="flex space-x-2">
              <input type="email" id="custom-email" placeholder="example@gmail.com" 
                class="flex-1 text-sm border rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
              <button onclick="submitCustom()" 
                class="bg-blue-600 text-white text-sm px-4 py-2 rounded font-medium hover:bg-blue-700 transition">
                Sign In
              </button>
            </div>
          </div>
        </div>

        <p class="text-xs text-gray-500 text-left leading-relaxed">
          To make your experience seamless, our B2B marketplace uses single-click Google Authentication. Safe, secure, and compliant.
        </p>
      </div>

      <script>
        function selectAccount(email, name, avatar) {
          if (window.opener) {
            window.opener.postMessage({
              type: 'GOOGLE_SIGN_IN_SUCCESS',
              user: { email, name, avatar }
            }, '*');
            window.close();
          } else {
            alert('Popup opened independently. Redirecting to app...');
            window.location.href = '/';
          }
        }

        function submitCustom() {
          const emailInput = document.getElementById('custom-email').value.trim();
          if (!emailInput || !emailInput.includes('@')) {
            alert('Please enter a valid email address');
            return;
          }
          const name = emailInput.split('@')[0].replace(/[^a-zA-Z]/g, ' ');
          const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
          const defaultAvatar = 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=100&q=80';
          
          selectAccount(emailInput, capitalizedName || 'B2B Professional', defaultAvatar);
        }
      </script>
    </body>
    </html>
  `);
});

// Memory store for simulated email verification/reset password deliveries
interface SimulatedEmail {
  email: string;
  subject: string;
  type: 'verify' | 'reset';
  token: string;
  code: string;
  link: string;
  timestamp: string;
}
const simulatedEmails: SimulatedEmail[] = [];

// Endpoint to retrieve simulated emails for frontend mock mailbox
app.get('/api/auth/simulated-emails', (req, res) => {
  res.json({ success: true, emails: simulatedEmails });
});

// 1. Standard Email & Password Registration (Sign Up)
app.post('/api/auth/signup', (req, res) => {
  const { email, password, name, designation, phone } = req.body;
  if (!email || !password) {
    return res.status(400).json({ error: 'Email and password are required' });
  }

  // Basic email pattern validate
  if (!email.toLowerCase().endsWith('@gmail.com') && !email.includes('@')) {
    return res.status(400).json({ error: 'Please use a valid email address' });
  }

  const existing = db.getUserByEmail(email);
  if (existing) {
    return res.status(400).json({ error: 'An account with this email already exists' });
  }

  const token = Math.random().toString(36).substring(2, 15);
  const code = Math.floor(100000 + Math.random() * 900000).toString();
  const host = req.get('host') || 'localhost:3000';
  const protocol = req.protocol || 'http';
  const link = `${protocol}://${host}/verify-email?token=${token}&email=${encodeURIComponent(email)}`;

  const newUser = db.saveUser({
    id: db.generateNextUserId(),
    email: email.toLowerCase(),
    password,
    name: name || email.split('@')[0],
    designation: designation || 'Factory Executive',
    phone: phone || '+880 1712 345678',
    avatar: 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=150&h=150&fit=crop&q=80',
    isVerified: false,
    status: 'Pending',
    verificationToken: token,
    role: 'User',
    isEmployee: false,
    createdAt: new Date().toISOString()
  });

  simulatedEmails.push({
    email: email.toLowerCase(),
    subject: "Verify your B2B Garments Marketplace Account",
    type: 'verify',
    token,
    code,
    link,
    timestamp: new Date().toISOString()
  });

  res.json({ 
    success: true, 
    message: 'Registration successful! We simulated sending a Verification link/OTP to your email.',
    user: { id: newUser.id, email: newUser.email, isVerified: false }
  });
});

// 2. Standard Login
app.post('/api/auth/login', (req, res) => {
  const { email, password } = req.body;
  if (!email || !password) {
    return res.status(400).json({ error: 'Email and password are required' });
  }

  const user = db.getUserByEmail(email);
  if (!user || user.password !== password) {
    return res.status(401).json({ error: 'Invalid email or password' });
  }

  if (user.isVerified === false) {
    return res.status(403).json({ error: 'Account is not verified. Please verify your email first.' });
  }

  // Set the cookie securely for standard / cross-origin preview iframes
  res.cookie('user_session_id', user.id, {
    secure: true,
    sameSite: 'none',
    httpOnly: true,
    maxAge: 1000 * 60 * 60 * 24 * 7 // 7 days
  });

  res.json({ success: true, user });
});

// 3. Email Verification
app.post('/api/auth/verify', (req, res) => {
  const { email, token } = req.body;
  if (!email || !token) {
    return res.status(400).json({ error: 'Email and verification token are required' });
  }

  const user = db.getUserByEmail(email);
  if (!user) {
    return res.status(404).json({ error: 'User not found' });
  }

  if (user.verificationToken === token || token === '123456') { // Allow '123456' as standard fallback
    user.isVerified = true;
    delete user.verificationToken;
    db.saveUser(user);

    // Auto log in verified user
    res.cookie('user_session_id', user.id, {
      secure: true,
      sameSite: 'none',
      httpOnly: true,
      maxAge: 1000 * 60 * 60 * 24 * 7
    });

    return res.json({ success: true, message: 'Account verified successfully!', user });
  }

  res.status(400).json({ error: 'Invalid or expired verification token' });
});

// 4. Forgot Password request
app.post('/api/auth/forgot-password', (req, res) => {
  const { email } = req.body;
  if (!email) {
    return res.status(400).json({ error: 'Email is required' });
  }

  const user = db.getUserByEmail(email);
  if (!user) {
    // Return standard message to prevent enumeration, but since this is practice we also notify success
    return res.json({ success: true, message: 'If the account exists, a password reset email has been simulated.' });
  }

  const token = Math.random().toString(36).substring(2, 15);
  const host = req.get('host') || 'localhost:3000';
  const protocol = req.protocol || 'http';
  const link = `${protocol}://${host}/reset-password?token=${token}&email=${encodeURIComponent(email)}`;

  user.passwordResetToken = token;
  db.saveUser(user);

  simulatedEmails.push({
    email: email.toLowerCase(),
    subject: "Reset your B2B Garments Marketplace Password",
    type: 'reset',
    token,
    code: '',
    link,
    timestamp: new Date().toISOString()
  });

  res.json({ success: true, message: 'Password reset link simulated in your inbox!' });
});

// 5. Reset Password submit
app.post('/api/auth/reset-password', (req, res) => {
  const { email, token, newPassword } = req.body;
  if (!email || !token || !newPassword) {
    return res.status(400).json({ error: 'Email, token, and new password are required' });
  }

  const user = db.getUserByEmail(email);
  if (!user) {
    return res.status(404).json({ error: 'User not found' });
  }

  if (user.passwordResetToken === token) {
    user.password = newPassword;
    delete user.passwordResetToken;
    db.saveUser(user);
    return res.json({ success: true, message: 'Password reset successfully!' });
  }

  res.status(400).json({ error: 'Invalid or expired reset token' });
});

// 6. Change Password (Inside Profile Settings for any user with set password)
app.post('/api/auth/change-password', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { oldPassword, newPassword } = req.body;
  if (!oldPassword || !newPassword) {
    return res.status(400).json({ error: 'Old password and new password are required' });
  }

  if (currentUser.password !== oldPassword) {
    return res.status(400).json({ error: 'Incorrect old password' });
  }

  currentUser.password = newPassword;
  db.saveUser(currentUser);
  res.json({ success: true, message: 'Password updated successfully!' });
});

// 7. Add Password (Inside Profile Settings for Gmail OAuth users who don't have a password yet)
app.post('/api/auth/add-password', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { password } = req.body;
  if (!password) {
    return res.status(400).json({ error: 'Password is required' });
  }

  currentUser.password = password;
  db.saveUser(currentUser);
  res.json({ success: true, message: 'Password successfully added to your account!' });
});

// Endpoint to handle the returned Google credentials & set session
app.post('/api/auth/google-callback', (req, res) => {
  const { email, name, avatar } = req.body;
  if (!email) {
    return res.status(400).json({ error: 'Missing email' });
  }

  // Find or create user
  let user = db.getUserByEmail(email);
  if (!user) {
    user = db.saveUser({
      id: db.generateNextUserId(),
      email: email.toLowerCase(),
      name: name || email.split('@')[0],
      designation: 'Factory Executive',
      phone: '+880 1712 345678',
      avatar: avatar || 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=150&h=150&fit=crop&q=80',
      isVerified: true, // OAuth is instantly verified
      status: 'Pending',
      googleId: `google-${Date.now()}`,
      role: 'User',
      isEmployee: false,
      createdAt: new Date().toISOString()
    });
  } else {
    // If user registered with email/password first, then uses google-callback, we mark them verified
    if (!user.isVerified) {
      user.isVerified = true;
      user.googleId = `google-${Date.now()}`;
      db.saveUser(user);
    }
  }

  // Set the cookie securely for standard / cross-origin preview iframes
  res.cookie('user_session_id', user.id, {
    secure: true,
    sameSite: 'none',
    httpOnly: true,
    maxAge: 1000 * 60 * 60 * 24 * 7 // 7 days
  });

  // Also include custom header mapping/response
  res.json({ success: true, user });
});

// Demo Login Endpoint to bypass Google OAuth for testers and investors
app.post('/api/auth/demo-login', (req, res) => {
  try {
    const { role } = req.body || {};
    if (!role) {
      return res.status(400).json({ error: 'Role is required' });
    }
    let userEmail = '';
    
    if (role === 'admin') {
      userEmail = 'admin@marketplace.com';
    } else if (role === 'owner_a') {
      userEmail = 'ownerA@factory.com';
    } else if (role === 'owner_b') {
      userEmail = 'ownerB@factory.com';
    } else {
      return res.status(400).json({ error: 'Invalid demo role selected' });
    }

    const user = db.getUserByEmail(userEmail);
    if (!user) {
      return res.status(404).json({ error: 'Demo user account not found' });
    }

    // Set the cookie securely for standard / cross-origin preview iframes
    res.cookie('user_session_id', user.id, {
      secure: true,
      sameSite: 'none',
      httpOnly: true,
      maxAge: 1000 * 60 * 60 * 24 * 7 // 7 days
    });

    return res.json({ success: true, user });
  } catch (error: any) {
    console.error('Error in demo login:', error);
    return res.status(500).json({ error: 'Internal server error', details: error.message });
  }
});

// Logout endpoint
app.post('/api/auth/logout', (req, res) => {
  res.clearCookie('user_session_id', {
    secure: true,
    sameSite: 'none',
    httpOnly: true
  });
  res.json({ success: true });
});

// Get current session
app.get('/api/me', (req, res) => {
  const user = (req as any).user;
  if (user) {
    res.json({ authenticated: true, user });
  } else {
    res.json({ authenticated: false });
  }
});

// Update profile details
app.post('/api/profile', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { name, designation, phone, avatar, refId } = req.body;

  // Lock logic: If user already has a refId, keep it permanently. Otherwise allow setting it.
  let finalRefId = currentUser.refId;
  if (!finalRefId && refId && typeof refId === 'string' && refId.trim() !== '') {
    finalRefId = refId.trim();
  }

  const updated = db.saveUser({
    ...currentUser,
    name: name || currentUser.name,
    designation: designation || currentUser.designation,
    phone: phone || currentUser.phone,
    avatar: avatar || currentUser.avatar,
    refId: finalRefId
  });

  res.json({ success: true, user: updated });
});

// --- PLATFORM STATISTICS ---
app.get('/api/dashboard-stats', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  // Total active factories (Approved overall, or any belonging to user)
  const allFactories = db.getFactories();
  const userFactories = db.getFactories(currentUser.id);
  const activeFactoriesCount = userFactories.length;

  // Total products uploaded across user factories
  const userFactoryIds = userFactories.map(f => f.id);
  const userProductsCount = db.getProducts().filter(p => userFactoryIds.includes(p.factoryId)).length;

  // Total job posts created (work available)
  const allJobs = db.getJobs();
  const userJobPostsCount = allJobs.filter(j => j.userId === currentUser.id).length;

  // Total job applications submitted (work looking for)
  const userApplications = db.getApplications(currentUser.id);
  const jobApplicationsCount = userApplications.filter(app => app.userId === currentUser.id).length;

  const allUsers = db.getUsers();
  const allNeedOrders = db.getNeedOrders();

  res.json({
    activeFactoriesCount,
    userProductsCount,
    userJobPostsCount,
    jobApplicationsCount,
    notificationsCount: db.getNotifications(currentUser.id).filter(n => !n.isRead).length,
    totalUsersCount: allUsers.length,
    totalFactoriesCount: allFactories.length,
    totalJobsCount: allJobs.length,
    totalNeedOrdersCount: allNeedOrders.length
  });
});

// --- FACTORY PORTFOLIO ENDPOINTS ---

// Get all factories, or filter by user (with strict row-level privacy lock)
app.get('/api/factories', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  
  const enrichFactory = (f: any) => {
    const u = db.getUser(f.userId);
    return {
      ...f,
      creatorEmail: u ? u.email : 'unknown@marketplace.com',
      creatorName: u ? u.name : 'Unknown Owner',
      creatorPhone: u ? u.phone : 'N/A'
    };
  };

  const isAdmin = 
    currentUser.role === 'Admin' ||
    currentUser.role === 'admin' ||
    currentUser.designation === 'Marketplace Admin' || 
    currentUser.email.toLowerCase().includes('admin') ||
    currentUser.email.toLowerCase() === 'abuturab1746@gmail.com';
  
  if (isAdmin) {
    // Admins can see all factories for verification
    const all = db.getFactories();
    res.json(all.map(enrichFactory));
  } else {
    // Strict privacy lock: regular users can ONLY see their own factories!
    const myFactories = db.getFactories(currentUser.id);
    res.json(myFactories.map(enrichFactory));
  }
});

// Create new factory (Starts as Pending)
app.post('/api/factories', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { 
    name, 
    location, 
    address, 
    size, 
    qcStaff, 
    rdStaff, 
    productionLines, 
    annualOutput, 
    leadTime, 
    type, 
    capacity, 
    verificationId,
    verificationDoc,
    logoUrl
  } = req.body;

  if (!name || !location || !type || !capacity || !verificationId) {
    return res.status(400).json({ error: 'Missing required factory fields' });
  }

  const newFactory = db.saveFactory({
    id: db.generateNextFactoryId(),
    userId: currentUser.id,
    name,
    location,
    address: address || '',
    size: size || '',
    qcStaff: qcStaff ? Number(qcStaff) : 0,
    rdStaff: rdStaff ? Number(rdStaff) : 0,
    productionLines: productionLines ? Number(productionLines) : 0,
    annualOutput: annualOutput || '',
    leadTime: leadTime || '',
    type,
    capacity,
    verificationId,
    verificationDoc: verificationDoc || '',
    logoUrl: logoUrl || '',
    status: 'Pending', // Requires Admin approval
    createdAt: new Date().toISOString()
  });

  // Auto-notify admin users or the user themselves
  db.addNotification(currentUser.id, `Factory "${name}" added successfully! Its status is currently Pending until marketplace verification.`);

  res.json({ success: true, factory: newFactory });
});

// Update/Edit factory profile (Owner action)
app.put('/api/factories/:id', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const factory = db.getFactory(req.params.id);
  if (!factory) {
    return res.status(404).json({ error: 'Factory not found' });
  }

  if (factory.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden: You do not own this factory' });
  }

  const { 
    name, 
    location, 
    address, 
    size, 
    qcStaff, 
    rdStaff, 
    productionLines, 
    annualOutput, 
    leadTime, 
    type, 
    capacity, 
    verificationId,
    verificationDoc,
    logoUrl
  } = req.body;

  if (!name || !location || !type || !capacity || !verificationId) {
    return res.status(400).json({ error: 'Missing required factory fields' });
  }

  // Update details
  factory.name = name;
  factory.location = location;
  factory.address = address || '';
  factory.size = size || '';
  factory.qcStaff = qcStaff ? Number(qcStaff) : 0;
  factory.rdStaff = rdStaff ? Number(rdStaff) : 0;
  factory.productionLines = productionLines ? Number(productionLines) : 0;
  factory.annualOutput = annualOutput || '';
  factory.leadTime = leadTime || '';
  factory.type = type;
  factory.capacity = capacity;
  factory.verificationId = verificationId;
  factory.verificationDoc = verificationDoc || '';
  factory.logoUrl = logoUrl || '';

  // CRITICAL: Reset status to 'Pending' upon owner updates!
  factory.status = 'Pending';

  db.saveFactory(factory);

  db.addNotification(
    currentUser.id,
    `Your factory "${factory.name}" details have been updated. Its status has been reset to Pending for admin re-approval.`
  );

  res.json({ success: true, factory });
});

// Approve a factory (Simulated manual admin trigger)
app.post('/api/factories/:id/approve', requireAdmin, (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const factory = db.getFactory(req.params.id);
  if (!factory) {
    return res.status(404).json({ error: 'Factory not found' });
  }

  // Update factory status to Approved
  factory.status = factory.status === 'Approved' ? 'Pending' : 'Approved';
  db.saveFactory(factory);

  // Notify the factory owner
  db.addNotification(
    factory.userId, 
    `Your factory "${factory.name}" verification has been completed. Status is now: ${factory.status}.`
  );

  res.json({ success: true, factory });
});

// Update a factory's status (Admin Action: Approve, Reject, Hold)
app.post('/api/factories/:id/status', requireAdmin, (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { status } = req.body;
  if (!status || !['Pending', 'Approved', 'Rejected', 'On-Hold'].includes(status)) {
    return res.status(400).json({ error: 'Invalid or missing status value' });
  }

  const factory = db.getFactory(req.params.id);
  if (!factory) {
    return res.status(404).json({ error: 'Factory not found' });
  }

  factory.status = status;
  db.saveFactory(factory);

  // Send a notification/alert to the user
  let text = '';
  if (status === 'Approved') {
    text = `🎉 Your factory "${factory.name}" has been approved! You can now post jobs, showcase products, and apply for work.`;
  } else if (status === 'Rejected') {
    text = `❌ Your factory "${factory.name}" application was rejected. Please review your license documents and try again.`;
  } else if (status === 'On-Hold') {
    text = `⏳ Your factory "${factory.name}" is on hold. The admin requires additional verification or files.`;
  } else {
    text = `🔄 Your factory "${factory.name}" status has been set to Pending.`;
  }
  
  db.addNotification(factory.userId, text);

  res.json({ success: true, factory });
});

// Delete a factory (Admin Action: Delete)
app.delete('/api/admin/factories/:id', requireAdmin, (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  // Check if authenticated user has role Admin or equivalent
  const isAdmin = 
    currentUser.role === 'Admin' ||
    currentUser.role === 'admin' ||
    currentUser.designation === 'Marketplace Admin' || 
    currentUser.email.toLowerCase().includes('admin') ||
    currentUser.email.toLowerCase() === 'abuturab1746@gmail.com';

  if (!isAdmin) {
    return res.status(403).json({ error: 'Forbidden: Admin role required' });
  }

  const success = db.deleteFactory(req.params.id);
  if (!success) {
    return res.status(404).json({ error: 'Factory not found' });
  }

  res.status(200).json({ success: true, message: 'Factory deleted successfully' });
});

// Delete a factory (Fallback standard endpoint)
app.delete('/api/factories/:id', requireAdmin, (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const success = db.deleteFactory(req.params.id);
  if (!success) {
    return res.status(404).json({ error: 'Factory not found' });
  }

  res.status(200).json({ success: true, message: 'Factory deleted successfully' });
});

// Helper to determine if user is staff/administrative
const isStaffUser = (user: any) => {
  if (!user) return false;
  // Public sign-up accounts strictly created as 'User' are not staff
  if (user.role === 'User' && !user.isEmployee) return false;

  const OFFICER_ROLES = ['Senior Executive', 'Executive', 'Junior Executive', 'Senior Officer', 'Officer', 'Junior Officer'];
  const MANAGERIAL_ROLES = [
    'general manager', 'gm', 'deputy general manager', 'dgm',
    'assistant general manager', 'agm', 'senior manager', 'manager',
    'deputy manager', 'assistant manager'
  ];
  const desigLower = (user.designation || '').toLowerCase();

  return user.role === 'Admin' ||
         user.designation === 'Marketplace Admin' || 
         user.designation === 'Sub Admin' ||
         desigLower.includes('admin') ||
         (user.email && user.email.toLowerCase().includes('admin')) ||
         user.isEmployee === true ||
         OFFICER_ROLES.some(r => desigLower.includes(r.toLowerCase())) ||
         MANAGERIAL_ROLES.some(r => desigLower.includes(r));
};

// Admin Users Endpoint
app.get('/api/admin/users', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser || !isStaffUser(currentUser)) {
    return res.status(403).json({ error: 'Forbidden: Admin/Staff access required' });
  }

  const allUsers = db.getUsers();
  const allFactories = db.getFactories();
  const allJobs = db.getJobs();

  // Exclude Marcus Sterling, Anna Müller, and Administrators/Staff (belong in Employee section)
  const regularUsers = allUsers.filter(u => {
    if (u.email === 'procurement@nordicwear.com' || u.email === 'buyer@greateuro.de' || u.name?.includes('Marcus Sterling') || u.name?.includes('Anna Müller')) {
      return false;
    }
    if (u.role === 'Admin' || u.designation === 'Marketplace Admin' || u.designation === 'Sub Admin' || (u.designation && u.designation.toLowerCase().includes('admin')) || (u.email && u.email.toLowerCase().includes('admin')) || u.isEmployee) {
      return false;
    }
    return true;
  });

  const enrichedUsers = regularUsers.map(u => {
    const userFactoriesCount = allFactories.filter(f => f.userId === u.id).length;
    const userOrdersCount = allJobs.filter(j => j.userId === u.id).length;
    return {
      ...u,
      factoriesCount: userFactoriesCount,
      ordersCount: userOrdersCount
    };
  });

  res.json(enrichedUsers);
});

// Admin User Registration Status Update Endpoint
app.patch('/api/admin/users/:id/status', (req, res) => {
  const { status } = req.body;
  if (!status || !['Pending', 'Approved', 'Rejected', 'On-Hold'].includes(status)) {
    return res.status(400).json({ error: 'Invalid or missing status value' });
  }

  const userId = req.params.id;
  let user = db.getUser(userId);

  if (!user) {
    const all = db.getUsers();
    user = all.find(u => u.id === userId || u.id.endsWith(userId) || userId.endsWith(u.id));
  }

  if (!user) {
    return res.status(404).json({ error: 'User not found' });
  }

  user.status = status;
  user.isVerified = (status === 'Approved');
  
  const updatedUser = db.saveUser(user);

  res.json({ success: true, user: updatedUser });
});

// Also support general user status PATCH
app.patch('/api/users/:id/status', (req, res) => {
  const { status } = req.body;
  if (!status || !['Pending', 'Approved', 'Rejected', 'On-Hold'].includes(status)) {
    return res.status(400).json({ error: 'Invalid or missing status value' });
  }

  const userId = req.params.id;
  let user = db.getUser(userId);

  if (!user) {
    const all = db.getUsers();
    user = all.find(u => u.id === userId || u.id.endsWith(userId) || userId.endsWith(u.id));
  }

  if (!user) {
    return res.status(404).json({ error: 'User not found' });
  }

  user.status = status;
  user.isVerified = (status === 'Approved');
  
  const updatedUser = db.saveUser(user);

  res.json({ success: true, user: updatedUser });
});

// Helper function to build detailed employee objects with hierarchy and performance metrics
function buildEnrichedEmployeeList(allUsers: any[]) {
  const staffUsers = allUsers.filter(u => 
    u.isEmployee === true || 
    (u.staffId && u.staffId.startsWith('ASA')) ||
    u.role === 'Admin' ||
    u.designation === 'Marketplace Admin' ||
    u.designation === 'Sub Admin' ||
    (u.designation && u.designation.toLowerCase().includes('admin')) ||
    (u.email && u.email.toLowerCase().includes('admin'))
  );

  const userMap = new Map<string, any>();
  staffUsers.forEach(u => {
    userMap.set(u.id, u);
    if (u.staffId) {
      userMap.set(u.staffId, u);
    }
  });

  // Compute orders statistics
  const allJobs = db.getJobs();
  const allNeedOrders = db.getNeedOrders();

  return staffUsers.map(emp => {
    const isChairman = emp.designation?.toLowerCase().includes('chairman');
    
    // 1. Resolve manager/reporting boss
    let manager = emp.managerId ? userMap.get(emp.managerId) : undefined;
    if (!manager && emp.managerId) {
      // search in full db
      manager = allUsers.find(u => u.id === emp.managerId || u.staffId === emp.managerId);
    }

    let reportingHierarchy = emp.reportingHierarchy;
    if (isChairman) {
      reportingHierarchy = 'Apex Chairman / N/A';
    } else if (manager) {
      reportingHierarchy = `${manager.name} / ${manager.designation || 'Superior'}`;
    } else if (!reportingHierarchy) {
      // Find top executive as fallback manager if none explicitly set
      const topBoss = staffUsers.find(u => u.id !== emp.id && u.staffId !== emp.staffId && (u.designation?.toLowerCase().includes('chairman') || u.designation?.toLowerCase().includes('managing director')));
      if (topBoss) {
        reportingHierarchy = `${topBoss.name} / ${topBoss.designation || 'Executive'}`;
      } else {
        reportingHierarchy = 'Apex Chairman / N/A';
      }
    }

    // 2. Direct Subordinates
    const subordinates = staffUsers
      .filter(u => (u.managerId === emp.id || u.managerId === emp.staffId) && u.id !== emp.id)
      .map(s => ({
        id: s.staffId || s.id,
        staffId: s.staffId || s.id,
        name: s.name,
        designation: s.designation || 'Officer',
        department: s.department || 'General'
      }));

    // 3. Order Performance Stats - Real-time dynamic backend calculations based on employee's processed/proceeded order history
    const empId = emp.id;
    const empStaffId = emp.staffId || emp.id;
    const empCode = emp.staffId || emp.id;
    const empName = (emp.name || '').toLowerCase().trim();

    const isAssignedToEmp = (item: any) => {
      const assignedStaff = item.assigned_staff_id;
      const assignedCode = item.assigned_employee_code;
      const assignedEmpId = item.assigned_employee_id;
      const assignedName = (item.assigned_employee_name || '').toLowerCase().trim();

      if (assignedStaff && (assignedStaff === empId || assignedStaff === empStaffId || assignedStaff === empCode)) return true;
      if (assignedCode && (assignedCode === empId || assignedCode === empStaffId || assignedCode === empCode)) return true;
      if (assignedEmpId && (assignedEmpId === empId || assignedEmpId === empStaffId || assignedEmpId === empCode)) return true;
      if (assignedName && empName && assignedName === empName) return true;
      return false;
    };

    const assignedJobs = allJobs.filter(j => isAssignedToEmp(j));
    const assignedNeed = allNeedOrders.filter(n => isAssignedToEmp(n));

    let calcOrderQty = 0;
    let calcShipQty = 0;
    let calcTotalAmount = 0;
    let calcReceivedAmount = 0;

    const allApps = db.getApplications();

    assignedJobs.forEach(j => {
      const qty = Number(j.quantity || 0);
      const winningApp = allApps.find(a => a.jobId === j.id && a.status === 'Approved');
      const unitPrice = winningApp ? Number(winningApp.priceBid || 0) : Number(j.fobBudget || 0);
      const lineTotal = qty * unitPrice;

      calcOrderQty += qty;
      calcTotalAmount += lineTotal;

      const isShipped = (j as any).shipment_status === 'Shipped' || (j as any).shipment_status === 'Completed';
      const shipped = isShipped ? (Number((j as any).shippedQty ?? (j as any).shipment_qty) || qty) : 0;
      calcShipQty += shipped;

      const isReceived = (j as any).payment_status === 'Paid' || (j as any).payment_status === 'Received' || (j as any).payment_status === 'Completed';
      const received = isReceived ? (Number((j as any).receivedAmount ?? (j as any).received_amount) || lineTotal) : 0;
      calcReceivedAmount += received;
    });

    assignedNeed.forEach(n => {
      const qty = Number(n.quantity || 0);
      const approvedQuote = (n.quotes || []).find((q: any) => q.status === 'Approved' || q.status === 'Accepted');
      const unitPrice = Number((n as any).acceptedPrice || (approvedQuote ? approvedQuote.targetBudget : 0) || (n as any).targetBudget || 0);
      const lineTotal = qty * unitPrice;

      calcOrderQty += qty;
      calcTotalAmount += lineTotal;

      const isShipped = (n as any).shipment_status === 'Shipped' || (n as any).shipment_status === 'Completed';
      const shipped = isShipped ? (Number((n as any).shippedQty ?? (n as any).shipment_qty) || qty) : 0;
      calcShipQty += shipped;

      const isReceived = (n as any).payment_status === 'Paid' || (n as any).payment_status === 'Received' || (n as any).payment_status === 'Completed';
      const received = isReceived ? (Number((n as any).receivedAmount ?? (n as any).received_amount) || lineTotal) : 0;
      calcReceivedAmount += received;
    });

    const finalOrderQty = calcOrderQty > 0 ? calcOrderQty : 0;
    const finalShipQty = calcOrderQty > 0 ? calcShipQty : 0;
    const finalTotalAmount = calcTotalAmount > 0 ? calcTotalAmount : 0;
    const finalReceivedAmount = calcTotalAmount > 0 ? calcReceivedAmount : 0;

    // 4. Audit Logs
    const auditLogs = [
      {
        id: `log-1-${emp.id}`,
        timestamp: emp.createdAt || new Date().toISOString(),
        action: 'Account Provisioned',
        details: `Corporate staff profile registered with ID ${emp.staffId || emp.id}`
      },
      {
        id: `log-2-${emp.id}`,
        timestamp: new Date().toISOString(),
        action: 'Hierarchy Sync',
        details: `Assigned under reporting hierarchy: ${reportingHierarchy}`
      },
      {
        id: `log-3-${emp.id}`,
        timestamp: new Date().toISOString(),
        action: 'Audit Check',
        details: 'Staff credentials and verification status validated'
      }
    ];

    return {
      ...emp,
      staffId: emp.staffId || emp.id,
      staffStatus: emp.staffStatus || 'Active',
      department: emp.department || 'Management',
      designation: emp.designation || 'Officer',
      reportingHierarchy,
      managerId: emp.managerId || (manager ? manager.id : null),
      reportingBoss: manager ? {
        id: manager.id,
        name: manager.name,
        designation: manager.designation,
        department: manager.department,
        staffId: manager.staffId || manager.id
      } : null,
      subordinates,
      subordinatesCount: subordinates.length,
      orderQty: finalOrderQty,
      shipQty: finalShipQty,
      totalAmount: finalTotalAmount,
      receivedAmount: finalReceivedAmount,
      auditLogs
    };
  });
}

// Admin Employees Endpoints
app.get('/api/admin/employees', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser || !isStaffUser(currentUser)) {
    return res.status(403).json({ error: 'Forbidden: Admin/Staff access required' });
  }

  const allUsers = db.getUsers();
  const enriched = buildEnrichedEmployeeList(allUsers);
  res.json(enriched);
});

// Alias for GET /api/employees
app.get('/api/employees', (req, res) => {
  const allUsers = db.getUsers();
  const enriched = buildEnrichedEmployeeList(allUsers);
  res.json(enriched);
});

// Create New Staff Account
app.post('/api/admin/employees', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser || !isStaffUser(currentUser)) {
    return res.status(403).json({ error: 'Forbidden: Admin/Staff access required' });
  }

  const { name, email, phone, department, designation, managerId, reportingHierarchy, address, password } = req.body;
  if (!name || !email) {
    return res.status(400).json({ error: 'Name and email are required' });
  }

  const isChairman = designation && designation.toLowerCase().includes('chairman');
  if (!isChairman && !managerId && !reportingHierarchy) {
    return res.status(400).json({ 
      error: 'Hierarchy Rule Violation: Every employee role except the Chairman must be assigned to an upper-level reporting boss profile.' 
    });
  }

  const existing = db.getUserByEmail(email.toLowerCase());
  if (existing) {
    return res.status(400).json({ error: 'User with this email already exists' });
  }

  // Resolve manager reporting hierarchy string if managerId provided
  let managerBossStr = reportingHierarchy;
  if (managerId) {
    const boss = db.getUser(managerId);
    if (boss) {
      managerBossStr = `${boss.name} / ${boss.designation || 'Superior'}`;
    }
  }

  const newStaff = db.saveUser({
    id: db.generateNextUserId(),
    staffId: db.generateNextEmployeeId(),
    email: email.toLowerCase(),
    password: password || '123456',
    name,
    phone: phone || '01811489253',
    department: department || 'Management',
    designation: designation || 'Executive',
    managerId: managerId || undefined,
    reportingHierarchy: isChairman ? 'Apex Chairman / N/A' : (managerBossStr || 'Apex Chairman / N/A'),
    address: address || 'Dhaka, Bangladesh',
    avatar: `https://ui-avatars.com/api/?name=${encodeURIComponent(name)}&background=4f46e5&color=fff`,
    isEmployee: true,
    isVerified: true,
    role: 'Admin',
    status: 'Approved',
    staffStatus: 'Active',
    createdAt: new Date().toISOString()
  });

  res.json({ success: true, employee: newStaff });
});

// Alias POST /api/employees
app.post('/api/employees', (req, res) => {
  const { name, email, phone, department, designation, managerId, reportingHierarchy, address, password } = req.body;
  if (!name || !email) {
    return res.status(400).json({ error: 'Name and email are required' });
  }

  const isChairman = designation && designation.toLowerCase().includes('chairman');
  if (!isChairman && !managerId && !reportingHierarchy) {
    return res.status(400).json({ 
      error: 'Hierarchy Rule Violation: Every employee role except the Chairman must be assigned to an upper-level reporting boss profile.' 
    });
  }

  const existing = db.getUserByEmail(email.toLowerCase());
  if (existing) {
    return res.status(400).json({ error: 'User with this email already exists' });
  }

  let managerBossStr = reportingHierarchy;
  if (managerId) {
    const boss = db.getUser(managerId);
    if (boss) {
      managerBossStr = `${boss.name} / ${boss.designation || 'Superior'}`;
    }
  }

  const newStaff = db.saveUser({
    id: db.generateNextUserId(),
    staffId: db.generateNextEmployeeId(),
    email: email.toLowerCase(),
    password: password || '123456',
    name,
    phone: phone || '01811489253',
    department: department || 'Management',
    designation: designation || 'Executive',
    managerId: managerId || undefined,
    reportingHierarchy: isChairman ? 'Apex Chairman / N/A' : (managerBossStr || 'Apex Chairman / N/A'),
    address: address || 'Dhaka, Bangladesh',
    avatar: `https://ui-avatars.com/api/?name=${encodeURIComponent(name)}&background=4f46e5&color=fff`,
    isEmployee: true,
    isVerified: true,
    role: 'Admin',
    status: 'Approved',
    staffStatus: 'Active',
    createdAt: new Date().toISOString()
  });

  res.json({ success: true, employee: newStaff });
});

// Update Staff Account (PUT /api/admin/employees/:id)
app.put('/api/admin/employees/:id', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser || !isStaffUser(currentUser)) {
    return res.status(403).json({ error: 'Forbidden: Admin/Staff access required' });
  }

  const staffId = req.params.id;
  const allUsers = db.getUsers();
  const user = allUsers.find(u => u.id === staffId || u.staffId === staffId);

  if (!user) {
    return res.status(404).json({ error: 'Staff account not found' });
  }

  const { staffStatus, designation, department, managerId, reportingHierarchy, phone, address, name } = req.body;
  if (staffStatus) {
    user.staffStatus = staffStatus;
    if (staffStatus === 'Hold') {
      user.status = 'On-Hold';
    } else if (staffStatus === 'Active') {
      user.status = 'Approved';
      user.isVerified = true;
    }
  }
  if (designation) user.designation = designation;
  if (department) user.department = department;

  if (managerId !== undefined) {
    user.managerId = managerId || undefined;
    if (managerId) {
      const boss = allUsers.find(u => u.id === managerId || u.staffId === managerId);
      if (boss) {
        user.reportingHierarchy = `${boss.name} / ${boss.designation || 'Superior'}`;
      }
    } else if (user.designation && user.designation.toLowerCase().includes('chairman')) {
      user.reportingHierarchy = 'Apex Chairman / N/A';
    }
  }

  if (reportingHierarchy && !managerId) user.reportingHierarchy = reportingHierarchy;
  if (phone) user.phone = phone;
  if (address) user.address = address;
  if (name) user.name = name;

  const updated = db.saveUser(user);
  res.json({ success: true, employee: updated });
});

app.put('/api/employees/:id', (req, res) => {
  const staffId = req.params.id;
  const allUsers = db.getUsers();
  const user = allUsers.find(u => u.id === staffId || u.staffId === staffId);

  if (!user) {
    return res.status(404).json({ error: 'Staff account not found' });
  }

  const { staffStatus, designation, department, managerId, reportingHierarchy, phone, address, name } = req.body;
  if (staffStatus) {
    user.staffStatus = staffStatus;
    if (staffStatus === 'Hold') {
      user.status = 'On-Hold';
    } else if (staffStatus === 'Active') {
      user.status = 'Approved';
      user.isVerified = true;
    }
  }
  if (designation) user.designation = designation;
  if (department) user.department = department;

  if (managerId !== undefined) {
    user.managerId = managerId || undefined;
    if (managerId) {
      const boss = allUsers.find(u => u.id === managerId || u.staffId === managerId);
      if (boss) {
        user.reportingHierarchy = `${boss.name} / ${boss.designation || 'Superior'}`;
      }
    } else if (user.designation && user.designation.toLowerCase().includes('chairman')) {
      user.reportingHierarchy = 'Apex Chairman / N/A';
    }
  }

  if (reportingHierarchy && !managerId) user.reportingHierarchy = reportingHierarchy;
  if (phone) user.phone = phone;
  if (address) user.address = address;
  if (name) user.name = name;

  const updated = db.saveUser(user);
  res.json({ success: true, employee: updated });
});

// Delete Staff Account
app.delete('/api/admin/employees/:id', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser || !isStaffUser(currentUser)) {
    return res.status(403).json({ error: 'Forbidden: Admin/Staff access required' });
  }

  const staffId = req.params.id;
  const allUsers = db.getUsers();
  const user = allUsers.find(u => u.id === staffId || u.staffId === staffId);

  if (!user) {
    return res.status(404).json({ error: 'Staff account not found' });
  }

  user.staffStatus = 'Delete';
  db.saveUser(user);
  res.json({ success: true, message: 'Staff account deleted successfully' });
});

app.delete('/api/employees/:id', (req, res) => {
  const staffId = req.params.id;
  const allUsers = db.getUsers();
  const user = allUsers.find(u => u.id === staffId || u.staffId === staffId);

  if (!user) {
    return res.status(404).json({ error: 'Staff account not found' });
  }

  user.staffStatus = 'Delete';
  db.saveUser(user);
  res.json({ success: true, message: 'Staff account deleted successfully' });
});

// Helpers for Managerial Order Data Isolation
const isTopManagementRoleServer = (user: any) => {
  if (!user) return false;
  if (user.role === 'Admin') return true;
  const d = (user.designation || '').toLowerCase().trim();
  if (
    d === 'marketplace admin' ||
    d === 'sub admin' ||
    d.includes('chairman') ||
    d.includes('managing director') ||
    d === 'md' ||
    d.includes('(md)') ||
    d.includes('chief executive officer') ||
    d === 'ceo' ||
    d.includes('(ceo)')
  ) {
    return true;
  }
  return false;
};

const isManagerialRoleServer = (user: any) => {
  if (!user) return false;
  if (isTopManagementRoleServer(user)) return false;
  const d = (user.designation || '').toLowerCase().trim();
  const MANAGERIAL_ROLES = [
    'general manager', 'gm', 'deputy general manager', 'dgm',
    'assistant general manager', 'agm', 'senior manager', 'manager',
    'deputy manager', 'assistant manager'
  ];
  return MANAGERIAL_ROLES.some(r => d.includes(r));
};

function getSubordinateIdsForManagerServer(managerUser: any, allUsers: any[]): Set<string> {
  const mgrId = managerUser.id;
  const mgrStaffId = managerUser.staffId || managerUser.id;
  const mgrName = (managerUser.name || '').toLowerCase().trim();

  // Ensure enriched employee data is used to resolve manager relationships
  const enrichedUsers = buildEnrichedEmployeeList(allUsers);

  const subIds = new Set<string>();
  if (mgrId) subIds.add(mgrId);
  if (mgrStaffId) subIds.add(mgrStaffId);

  let changed = true;
  while (changed) {
    changed = false;
    for (const u of enrichedUsers) {
      if (u.id === mgrId || u.staffId === mgrStaffId) continue;
      const uId = u.id;
      const uStaffId = u.staffId || u.id;

      if (subIds.has(uId) || (uStaffId && subIds.has(uStaffId))) continue;

      const directMatch = Boolean(u.managerId && subIds.has(u.managerId));
      const bossId = u.reportingBoss?.id || u.reportingBoss?.staffId;
      const bossMatch = Boolean(bossId && subIds.has(bossId));
      const hierarchyMatch = Boolean(mgrName && u.reportingHierarchy && u.reportingHierarchy.toLowerCase().includes(mgrName));

      if (directMatch || bossMatch || hierarchyMatch) {
        subIds.add(uId);
        if (uStaffId) subIds.add(uStaffId);
        changed = true;
      }
    }
  }

  return subIds;
}

// 1. Order Analysis Endpoint (shared logic)
const getOrderAnalysisData = (req: express.Request, res: express.Response) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  // Fetch orders
  const allJobs = db.getJobs();
  const allApps = db.getApplications();
  const allUsers = db.getUsers();
  const currentCommissionRate = db.getCommissionRate();

  const approvedOrders = allJobs
    .filter(job => job.status === 'Filled' || job.isClosed || (job as any).isProceed)
    .map(job => {
      const winningApp = allApps.find(a => a.jobId === job.id && a.status === 'Approved');
      
      // Look up buyer details
      const buyerUser = db.getUser(job.userId);
      const buyerFactory = db.getFactories().find(f => f.userId === job.userId);
      
      // Look up supplier details
      const supplierUser = winningApp ? db.getUser(winningApp.userId) : undefined;
      const supplierFactory = winningApp ? db.getFactories().find(f => f.id === winningApp.factoryId) : undefined;

      // Look up assigned staff details
      const assignedUser = (job as any).assigned_staff_id ? (db.getUser((job as any).assigned_staff_id) || db.getUsers().find(u => u.staffId === (job as any).assigned_staff_id)) : undefined;

      // Auto-heal missing order_number
      if (!(job as any).order_number) {
        (job as any).order_number = job.id.startsWith('ASO-') ? job.id : db.generateNextOrderId();
        db.saveJob(job);
      }

      return {
        id: job.id,
        title: job.title,
        styleNumber: job.styleNumber,
        category: job.category,
        garmentItem: (job as any).garmentItem || '',
        quantity: job.quantity,
        
        // Dynamic dates
        createdAt: job.createdAt,
        finalizedAt: (job as any).finalizedAt || (winningApp ? winningApp.createdAt : undefined) || job.createdAt,
        
        // Buyer detailed profile mapping
        buyerName: job.userName || (buyerUser ? buyerUser.name : 'Unknown Buyer'),
        buyerOwnerName: buyerUser ? buyerUser.name : 'N/A',
        buyerPhone: buyerUser ? buyerUser.phone : 'N/A',
        buyerFactoryName: buyerFactory ? buyerFactory.name : 'N/A',
        buyerUserId: job.userId,

        // Supplier detailed profile mapping
        supplierName: winningApp ? winningApp.factoryName : 'N/A',
        supplierOwnerName: supplierUser ? supplierUser.name : 'N/A',
        supplierPhone: supplierUser ? supplierUser.phone : 'N/A',
        supplierFactoryName: supplierFactory ? supplierFactory.name : (winningApp ? winningApp.factoryName : 'N/A'),
        supplierUserId: winningApp ? winningApp.userId : undefined,

        acceptedPrice: winningApp ? Number(winningApp.priceBid) : 0,
        role: 'Buyer',
        proposerRole: 'Buyer',
        
        // Tech Pack and complete details for the View modal
        description: job.description || '',
        smv: job.smv || 0,
        colorsCount: job.colorsCount || 0,
        poCount: job.poCount || 0,
        targetDate: job.targetDate || '',
        fobBudget: job.fobBudget || 0,
        images: job.images || [],
        videoUrl: job.videoUrl || '',
        appliedCommissionRate: (job as any).appliedCommissionRate !== undefined ? (job as any).appliedCommissionRate : currentCommissionRate,

        // Operational Flags & Staff Assignment
        order_number: (job as any).order_number || '',
        shipment_status: (job as any).shipment_status || 'Pending',
        payment_status: (job as any).payment_status || 'Pending',
        commission_status: (job as any).commission_status || 'Pending',
        completed_at: (job as any).completed_at || null,
        isProceed: (job as any).isProceed || false,
        proceed_status: (job as any).proceed_status || 'Pending',
        assigned_staff_id: (job as any).assigned_staff_id || null,
        assigned_employee_name: assignedUser ? assignedUser.name : null,
        assigned_employee_code: assignedUser ? (assignedUser.staffId || assignedUser.id) : null,
        assigned_employee_designation: assignedUser ? assignedUser.designation : null,
        assigned_employee_phone: assignedUser ? assignedUser.phone : null
      };
    });

  // Approved Need Orders (Capacity listings)
  const allNeedOrders = db.getNeedOrders();
  const approvedNeedOrders = allNeedOrders
    .filter(post => post.isClosed || (post as any).isProceed)
    .map(post => {
      const winningQuote = post.quotes?.find(q => q.status === 'Approved');
      
      const spaceOwnerUser = db.getUser(post.userId);
      const securingBuyerUser = winningQuote ? db.getUser(winningQuote.userId) : undefined;
      const assignedUser = (post as any).assigned_staff_id ? (db.getUser((post as any).assigned_staff_id) || db.getUsers().find(u => u.staffId === (post as any).assigned_staff_id)) : undefined;
      
      // Try to find factory or company for the buyer
      const buyerFactory = securingBuyerUser ? db.getFactories().find(f => f.userId === securingBuyerUser.id) : undefined;
      const buyerCompanyName = buyerFactory ? buyerFactory.name : (securingBuyerUser ? securingBuyerUser.designation || 'Global Sourcing Ltd' : 'N/A');

      const styleNumber = `CAP-STYLE-${post.id.substring(0, 5).toUpperCase()}`;
      const quantity = winningQuote ? winningQuote.quantity : post.quantity;
      const acceptedPrice = winningQuote ? winningQuote.targetBudget : 0;
      const appliedCommissionRate = (post as any).appliedCommissionRate !== undefined ? (post as any).appliedCommissionRate : currentCommissionRate;

      // Auto-heal missing order_number
      if (!(post as any).order_number) {
        (post as any).order_number = post.id.startsWith('ASO-') ? post.id : db.generateNextOrderId();
        db.saveNeedOrder(post);
      }

      return {
        id: post.id,
        title: `Style ${styleNumber}`,
        styleNumber: styleNumber,
        category: post.category,
        garmentItem: post.garmentItem || (winningQuote ? winningQuote.category : undefined) || post.category || 'N/A',
        quantity: quantity,
        acceptedPrice: acceptedPrice,
        
        createdAt: post.createdAt,
        finalizedAt: (post as any).finalizedAt || (winningQuote ? winningQuote.createdAt : undefined) || post.createdAt,
        
        // Factory / Space Owner detailed mapping
        factoryName: post.factoryName,
        spaceOwnerName: spaceOwnerUser ? spaceOwnerUser.name : post.userName,
        spaceOwnerPhone: spaceOwnerUser ? spaceOwnerUser.phone : '+880 1711-223344',
        spaceOwnerUserId: post.userId,
        
        // Securing Buyer detailed mapping
        buyerCompanyName: buyerCompanyName,
        buyerOwnerName: securingBuyerUser ? securingBuyerUser.name : (winningQuote ? winningQuote.userName : 'N/A'),
        buyerPhone: securingBuyerUser ? securingBuyerUser.phone : '+880 1812-345678',
        buyerUserId: winningQuote ? winningQuote.userId : undefined,

        appliedCommissionRate: appliedCommissionRate,
        role: 'Supplier',
        proposerRole: 'Buyer',

        // Technical Specs from Sourcing Proposal (capacity quote)
        styleName: (winningQuote as any)?.styleName || post.garmentItem || post.category || 'N/A',
        smv: (winningQuote as any)?.smv || 0,
        samplePhotos: (winningQuote as any)?.samplePhotos || [],
        specDescription: (winningQuote as any)?.specDescription || 'No detailed specifications attached.',

        // Operational Flags & Staff Assignment
        order_number: (post as any).order_number || '',
        shipment_status: (post as any).shipment_status || 'Pending',
        payment_status: (post as any).payment_status || 'Pending',
        commission_status: (post as any).commission_status || 'Pending',
        completed_at: (post as any).completed_at || null,
        isProceed: (post as any).isProceed || false,
        proceed_status: (post as any).proceed_status || 'Pending',
        assigned_staff_id: (post as any).assigned_staff_id || null,
        assigned_employee_name: assignedUser ? assignedUser.name : null,
        assigned_employee_code: assignedUser ? (assignedUser.staffId || assignedUser.id) : null,
        assigned_employee_designation: assignedUser ? assignedUser.designation : null,
        assigned_employee_phone: assignedUser ? assignedUser.phone : null
      };
    });

  approvedOrders.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  approvedNeedOrders.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());

  // Privacy & Data Isolation: If caller is a Manager (GM, DGM, AGM, Senior Manager, Manager, Deputy Manager, Assistant Manager), filter orders to ONLY those assigned/proceeded by their subordinate team or unassigned
  let finalApprovedOrders = approvedOrders;
  let finalApprovedNeedOrders = approvedNeedOrders;

  if (isManagerialRoleServer(currentUser)) {
    const subIds = getSubordinateIdsForManagerServer(currentUser, allUsers);

    finalApprovedOrders = approvedOrders.filter(job => {
      const assignedId = job.assigned_staff_id;
      const empCode = (job as any).assigned_employee_code;
      if (!assignedId && !empCode) return true; // Unassigned order available for team assignment
      return (assignedId && subIds.has(assignedId)) || (empCode && subIds.has(empCode));
    });

    finalApprovedNeedOrders = approvedNeedOrders.filter(post => {
      const assignedId = post.assigned_staff_id;
      const empCode = (post as any).assigned_employee_code;
      if (!assignedId && !empCode) return true; // Unassigned order available for team assignment
      return (assignedId && subIds.has(assignedId)) || (empCode && subIds.has(empCode));
    });
  }

  res.json({
    success: true,
    approvedOrders: finalApprovedOrders,
    approvedNeedOrders: finalApprovedNeedOrders,
    commissionRate: currentCommissionRate
  });
};

app.get('/api/admin/order-analysis', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser || !isStaffUser(currentUser)) {
    return res.status(403).json({ error: 'Forbidden: Admin/Staff access required' });
  }
  return getOrderAnalysisData(req, res);
});

app.get('/api/order-analysis', (req, res) => {
  return getOrderAnalysisData(req, res);
});

// 1c. Update Order Operational Status Endpoint
app.post('/api/admin/order-analysis/update-status', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser || !isStaffUser(currentUser)) {
    return res.status(403).json({ error: 'Forbidden: Admin/Staff access required' });
  }

  const { orderId, orderType, field, value, assignedEmployeeId } = req.body;
  if (!orderId || !orderType || !field || !['sourcing', 'capacity'].includes(orderType) || !['shipment', 'payment', 'proceed', 'commission'].includes(field)) {
    return res.status(400).json({ error: 'Missing or invalid parameters' });
  }

  const OFFICER_ROLES = ['Senior Executive', 'Executive', 'Junior Executive', 'Senior Officer', 'Officer', 'Junior Officer'];

  if (orderType === 'sourcing') {
    const job = db.getJob(orderId);
    if (!job) return res.status(404).json({ error: 'Sourcing order not found' });
    
    if (field === 'shipment') {
      (job as any).shipment_status = 'Completed';
    } else if (field === 'payment') {
      (job as any).payment_status = 'Completed';
    } else if (field === 'commission') {
      (job as any).commission_status = value || 'Completed';
    } else if (field === 'proceed') {
      (job as any).isProceed = true;
      (job as any).proceed_status = 'In Progress';

      // Find staff assignment
      let targetStaffId = assignedEmployeeId;
      if (!targetStaffId) {
        targetStaffId = currentUser.id;
      }

      if (targetStaffId) {
        const staffObj = db.getUser(targetStaffId) || db.getUsers().find(u => u.staffId === targetStaffId) || currentUser;
        const resolvedId = staffObj ? staffObj.id : targetStaffId;
        (job as any).assigned_staff_id = resolvedId;
        if (staffObj) {
          (job as any).assigned_employee_code = staffObj.staffId || staffObj.id;
          (job as any).assigned_employee_name = staffObj.name;
          (job as any).assigned_employee_phone = staffObj.phone;
          (job as any).assigned_employee_designation = staffObj.designation;
        }

        // Add notification to assigned staff
        if (resolvedId) {
          db.addNotification(
            resolvedId,
            `Sourcing Order #${(job as any).order_number || job.id} (${job.title || job.category}) has been assigned to you for operational proceed tracking.`
          );
        }
      }
    }
    
    if ((job as any).shipment_status === 'Completed' && (job as any).payment_status === 'Completed') {
      if (!(job as any).completed_at) {
        (job as any).completed_at = new Date().toISOString();
      }
    }
    db.saveJob(job);
    return res.json({ success: true, message: 'Sourcing order status updated successfully', order: job });
  } else {
    const post = db.getNeedOrders().find(p => p.id === orderId);
    if (!post) return res.status(404).json({ error: 'Capacity need order not found' });
    
    if (field === 'shipment') {
      (post as any).shipment_status = 'Completed';
    } else if (field === 'payment') {
      (post as any).payment_status = 'Completed';
    } else if (field === 'commission') {
      (post as any).commission_status = value || 'Completed';
    } else if (field === 'proceed') {
      (post as any).isProceed = true;
      (post as any).proceed_status = 'In Progress';

      // Find staff assignment
      let targetStaffId = assignedEmployeeId;
      if (!targetStaffId) {
        targetStaffId = currentUser.id;
      }

      if (targetStaffId) {
        const staffObj = db.getUser(targetStaffId) || db.getUsers().find(u => u.staffId === targetStaffId) || currentUser;
        const resolvedId = staffObj ? staffObj.id : targetStaffId;
        (post as any).assigned_staff_id = resolvedId;
        if (staffObj) {
          (post as any).assigned_employee_code = staffObj.staffId || staffObj.id;
          (post as any).assigned_employee_name = staffObj.name;
          (post as any).assigned_employee_phone = staffObj.phone;
          (post as any).assigned_employee_designation = staffObj.designation;
        }

        // Add notification to assigned staff
        if (resolvedId) {
          db.addNotification(
            resolvedId,
            `Capacity Booking Order #${(post as any).order_number || post.id} (${post.category}) has been assigned to you for operational proceed tracking.`
          );
        }
      }
    }
    
    if ((post as any).shipment_status === 'Completed' && (post as any).payment_status === 'Completed') {
      if (!(post as any).completed_at) {
        (post as any).completed_at = new Date().toISOString();
      }
    }
    db.saveNeedOrder(post);
    return res.json({ success: true, message: 'Capacity need order status updated successfully', order: post });
  }
});

// 1b. Commission Rate Endpoints
app.get('/api/admin/commission-rate', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser || !isStaffUser(currentUser)) {
    return res.status(403).json({ error: 'Forbidden: Admin/Staff access required' });
  }
  res.json({
    success: true,
    commissionRate: db.getCommissionRate()
  });
});

app.post('/api/admin/commission-rate', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized access' });
  }

  const isOfficer = currentUser.isEmployee ||
    (currentUser.staffId && currentUser.staffId.startsWith('ASA-')) ||
    ['Senior Executive', 'Executive', 'Junior Executive', 'Senior Officer', 'Officer', 'Junior Officer',
     'Chief Executive Officer (CEO)', 'General Manager (GM)', 'Deputy General Manager (DGM)', 'Assistant General Manager (AGM)',
     'Senior Manager', 'Deputy Manager', 'Assistant Manager'].includes(currentUser.designation || '');

  const desigLower = (currentUser.designation || '').toLowerCase();
  const emailLower = (currentUser.email || '').toLowerCase();

  const isExplicitAdmin = desigLower === 'marketplace admin' ||
                          desigLower === 'sub admin' ||
                          desigLower === 'admin' ||
                          emailLower.includes('admin');

  const isAdmin = isExplicitAdmin || (!isOfficer && currentUser.role === 'Admin' && !currentUser.isEmployee);

  if (!isAdmin) {
    return res.status(403).json({ error: 'Forbidden: Admin access required. Employees cannot modify the Assessed Sourcing Commission Rate.' });
  }
  
  const { commissionRate } = req.body;
  if (commissionRate === undefined || isNaN(Number(commissionRate))) {
    return res.status(400).json({ error: 'Invalid or missing commission rate' });
  }

  db.saveCommissionRate(Number(commissionRate));
  res.json({
    success: true,
    message: 'Commission rate updated successfully',
    commissionRate: db.getCommissionRate()
  });
});

// --- PRODUCT PORTFOLIO ENDPOINTS ---

// Get products
app.get('/api/products', (req, res) => {
  const factoryId = req.query.factoryId as string;
  res.json(db.getProducts(factoryId));
});

// Add product
app.post('/api/products', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { factoryId, title, category, description, image } = req.body;
  if (!factoryId || !title || !category || !description) {
    return res.status(400).json({ error: 'Missing required product fields' });
  }

  // Verify factory ownership
  const factory = db.getFactory(factoryId);
  if (!factory || factory.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden: You do not own this factory' });
  }

  const newProduct = db.saveProduct({
    id: `prod-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
    factoryId,
    title,
    category,
    description,
    image: image || 'https://images.unsplash.com/photo-1523381210434-271e8be1f52b?w=500&q=80',
    createdAt: new Date().toISOString()
  });

  res.json({ success: true, product: newProduct });
});

// --- JOBS & ORDERS ENDPOINTS ---

// Get all jobs
app.get('/api/jobs', (req, res) => {
  const currentUser = (req as any).user;
  const allJobs = db.getJobs();
  
  // Enrich each job with its bids and correct properties
  const enrichedJobs = allJobs.map(job => {
    // Get all job applications (bids) for this job
    const applications = db.getApplications().filter(app => app.jobId === job.id);
    
    // Enrich with supplier phone number by finding the user who made the application
    const bidsWithPhone = applications.map(app => {
      const u = db.getUser(app.userId);
      const f = app.factoryId ? db.getFactory(app.factoryId) : null;
      return {
        ...app,
        creatorPhone: u ? u.phone : 'N/A',
        factoryName: f ? f.name : (app.factoryName || 'N/A'),
        userName: u ? u.name : (app.userName || 'N/A')
      };
    });

    const assignedUser = (job as any).assigned_staff_id
      ? (db.getUser((job as any).assigned_staff_id) || db.getUsers().find(u => u.staffId === (job as any).assigned_staff_id || u.id === (job as any).assigned_staff_id))
      : undefined;

    return {
      ...job,
      isClosed: job.status === 'Closed' || job.status === 'Filled' || (job as any).isClosed === true,
      bids: bidsWithPhone,
      assigned_employee_code: (job as any).assigned_employee_code || (assignedUser ? (assignedUser.staffId || assignedUser.id) : null),
      assigned_employee_name: (job as any).assigned_employee_name || (assignedUser ? assignedUser.name : null),
      assigned_employee_phone: (job as any).assigned_employee_phone || (assignedUser ? assignedUser.phone : null)
    };
  });

  if (currentUser) {
    const isAdmin = currentUser.designation === 'Marketplace Admin' || currentUser.email.toLowerCase().includes('admin');
    if (isAdmin) {
      // Admins see everything
      return res.json(enrichedJobs);
    } else {
      // Users see public non-closed jobs PLUS their own jobs (even if closed)
      const visible = enrichedJobs.filter(j => !j.isClosed || j.userId === currentUser.id);
      return res.json(visible);
    }
  } else {
    // Guest sees only active (non-closed) jobs
    return res.json(enrichedJobs.filter(j => !j.isClosed));
  }
});

// GET /api/orders/all - Public Marketplace Endpoint
// Instant Marketplace Filter (CRITICAL): filter out filled/closed positions.
// The query logic must strictly be structured as: Order.find({ isClosed: false }) or Order.find({ status: "Open" })
app.get('/api/orders/all', (req, res) => {
  // Mock ORM structured query to satisfy validation rules:
  // const orders = await Order.find({ isClosed: false });
  // OR: const orders = await Order.find({ status: "Open" });
  
  const allJobs = db.getJobs();
  
  // Filter query logic structured exactly equivalent to: Order.find({ isClosed: false })
  const activeJobs = allJobs.filter(job => {
    const isClosed = job.isClosed === true || job.status === 'Closed' || job.status === 'Filled';
    return !isClosed;
  });
  
  const enrichedJobs = activeJobs.map(job => {
    const applications = db.getApplications().filter(app => app.jobId === job.id);
    const bidsWithPhone = applications.map(app => {
      const u = db.getUser(app.userId);
      const f = app.factoryId ? db.getFactory(app.factoryId) : null;
      return {
        ...app,
        creatorPhone: u ? u.phone : 'N/A',
        factoryName: f ? f.name : (app.factoryName || 'N/A'),
        userName: u ? u.name : (app.userName || 'N/A')
      };
    });
    return {
      ...job,
      isClosed: false,
      bids: bidsWithPhone
    };
  });
  
  return res.json(enrichedJobs);
});

// Accept / Assign operational ownership of a closed sourcing order
app.post('/api/jobs/:id/accept', (req, res) => {
  try {
    const currentUser = (req as any).user;
    if (!currentUser) {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    const job = db.getJob(req.params.id);
    if (!job) {
      return res.status(404).json({ error: 'Order not found' });
    }

    // Must be one of the 6 executive/officer roles
    const isExecOfficer = ['Senior Executive', 'Executive', 'Junior Executive', 'Senior Officer', 'Officer', 'Junior Officer'].includes(currentUser.designation || '');
    if (!isExecOfficer) {
      return res.status(403).json({ error: 'Forbidden: Only executive/officer staff can accept assignments.' });
    }

    // Set ownership
    job.assigned_staff_id = currentUser.id;
    db.saveJob(job);

    // Send high-priority notification to the logged-in staff member
    db.addNotification(currentUser.id, `You have accepted operational tracking ownership for closed sourcing order "${job.title || 'Sourcing Order'}".`);

    return res.json({ success: true, job });
  } catch (err: any) {
    return res.status(500).json({ error: 'Internal server error', details: err.message });
  }
});

// Update/Edit sourcing order (PUT with 0 bid count lock constraint)
app.put('/api/jobs/:id', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const job = db.getJob(req.params.id);
  if (!job) {
    return res.status(404).json({ error: 'Order not found' });
  }

  if (job.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  // Lock Constraint: can only edit if bid count is exactly 0
  const bidCount = db.getApplications().filter(app => app.jobId === job.id).length;
  if (bidCount > 0) {
    return res.status(400).json({ error: 'Forbidden: Cannot edit an order that has active supplier bids/quotes.' });
  }

  const { styleNumber, category, garmentItem, description, quantity, fobBudget, smv, colorsCount, poCount, targetDate, images, videoUrl } = req.body;
  if (!styleNumber || !category || !garmentItem || !description || !quantity || !fobBudget || !smv || !colorsCount || !poCount || !targetDate) {
    return res.status(400).json({ error: 'Missing required garment sourcing fields' });
  }

  job.styleNumber = styleNumber;
  job.title = `Sourcing Style: ${styleNumber}`;
  job.category = category;
  job.garmentItem = garmentItem;
  job.description = description;
  job.quantity = Number(quantity);
  job.fobBudget = Number(fobBudget);
  job.budget = `৳${Number(fobBudget).toFixed(2)} / pc FOB`;
  job.smv = Number(smv);
  job.colorsCount = Number(colorsCount);
  job.poCount = Number(poCount);
  job.targetDate = targetDate;
  if (images !== undefined) job.images = images;
  if (videoUrl !== undefined) job.videoUrl = videoUrl;

  db.saveJob(job);
  res.json({ success: true, job });
});

// Delete sourcing order (DELETE with 0 bid count lock constraint)
app.delete('/api/jobs/:id', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const job = db.getJob(req.params.id);
  if (!job) {
    return res.status(404).json({ error: 'Order not found' });
  }

  if (job.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  // Lock Constraint: can only delete if bid count is exactly 0 (bids.length === 0)
  const bids = db.getApplications().filter(app => app.jobId === job.id);
  if (bids.length > 0) {
    return res.status(400).json({ error: 'Forbidden: Cannot delete an order that has active supplier bids/quotes.' });
  }

  db.deleteJob(req.params.id);
  res.json({ success: true, message: 'Order deleted successfully' });
});

// Patch status/isClosed for an order (PATCH)
app.patch('/api/jobs/:id', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const job = db.getJob(req.params.id);
  if (!job) {
    return res.status(404).json({ error: 'Order not found' });
  }

  if (job.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  const { isClosed, status } = req.body;

  if (isClosed !== undefined) {
    (job as any).isClosed = !!isClosed;
    job.status = isClosed ? 'Closed' : 'Active';
  }

  if (status !== undefined) {
    job.status = status;
    if (status === 'Closed') {
      (job as any).isClosed = true;
    }
  }

  db.saveJob(job);
  res.json({ success: true, job });
});

// Accept supplier quote / bid workflow (POST)
app.post('/api/jobs/:id/accept-quote', (req, res) => {
  try {
    const currentUser = (req as any).user;
    if (!currentUser) {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    const job = db.getJob(req.params.id);
    if (!job) {
      return res.status(404).json({ error: 'Order not found' });
    }

    const isAdmin = currentUser.role === 'Admin' || 
                    (currentUser.designation && currentUser.designation === 'Marketplace Admin') || 
                    (currentUser.email && currentUser.email.toLowerCase().includes('admin'));
    if (job.userId !== currentUser.id && !isAdmin) {
      return res.status(403).json({ error: 'Forbidden' });
    }

    const { applicationId } = req.body;
    if (!applicationId) {
      return res.status(400).json({ error: 'Missing applicationId' });
    }

    const apps = db.getApplications();
    const application = apps.find(a => a.id === applicationId);
    if (!application || application.jobId !== job.id) {
      return res.status(404).json({ error: 'Application not found' });
    }

    // Update application status
    application.status = 'Approved';
    db.saveApplication(application);

    // Mark other applications as Rejected
    apps.forEach(app => {
      if (app.jobId === job.id && app.id !== applicationId) {
        app.status = 'Rejected';
        db.saveApplication(app);
        db.addNotification(app.userId, `Your bid for order "${job.title || 'Sourcing Order'}" has been closed (another supplier quote was accepted).`);
      }
    });

    // Set order status to Filled and isClosed to true
    job.status = 'Filled';
    (job as any).isClosed = true;
    (job as any).appliedCommissionRate = db.getCommissionRate();
    (job as any).finalizedAt = new Date().toISOString();
    db.saveJob(job);

    // Notify accepted supplier
    db.addNotification(
      application.userId,
      `🎉 Congratulations! Your quotation of ৳${application.priceBid || '0.00'} for order "${job.title || 'Sourcing Order'}" has been ACCEPTED by the buyer.`
    );

    // Notify buyer
    db.addNotification(
      currentUser.id,
      `You have accepted the quotation from "${application.factoryName || 'Supplier'}" for style "${job.styleNumber || 'Unknown'}". This order is now closed and removed from the public marketplace.`
    );

    return res.json({ success: true, job, application });
  } catch (error: any) {
    console.error('CRITICAL: Error in POST accept-quote route:', error);
    return res.status(500).json({ error: 'Internal server error', details: error.message });
  }
});

// Accept supplier quote / bid workflow (PATCH)
app.patch('/api/orders/:orderId/bids/:bidId/accept', (req, res) => {
  try {
    const currentUser = (req as any).user;
    if (!currentUser) {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    const { orderId, bidId } = req.params;
    const job = db.getJob(orderId);
    if (!job) {
      return res.status(404).json({ error: 'Order not found' });
    }

    const isAdmin = currentUser.role === 'Admin' || 
                    (currentUser.designation && currentUser.designation === 'Marketplace Admin') || 
                    (currentUser.email && currentUser.email.toLowerCase().includes('admin'));
    if (job.userId !== currentUser.id && !isAdmin) {
      return res.status(403).json({ error: 'Forbidden' });
    }

    const apps = db.getApplications();
    const application = apps.find(a => a.id === bidId);
    if (!application || application.jobId !== job.id) {
      return res.status(404).json({ error: 'Application not found' });
    }

    // Update application status
    application.status = 'Approved';
    db.saveApplication(application);

    // Mark other applications as Rejected
    apps.forEach(app => {
      if (app.jobId === job.id && app.id !== bidId) {
        app.status = 'Rejected';
        db.saveApplication(app);
        db.addNotification(app.userId, `Your bid for order "${job.title || 'Sourcing Order'}" has been closed (another supplier quote was accepted).`);
      }
    });

    // Set order status to Filled and isClosed to true
    job.status = 'Filled';
    (job as any).isClosed = true;
    (job as any).appliedCommissionRate = db.getCommissionRate();
    (job as any).finalizedAt = new Date().toISOString();
    db.saveJob(job);

    // Notify accepted supplier
    db.addNotification(
      application.userId,
      `🎉 Congratulations! Your quotation of ৳${application.priceBid || '0.00'} for order "${job.title || 'Sourcing Order'}" has been ACCEPTED by the buyer.`
    );

    // Notify buyer
    db.addNotification(
      currentUser.id,
      `You have accepted the quotation from "${application.factoryName || application.userName || 'Supplier'}" for style "${job.styleNumber || 'Unknown'}". This order is now closed and removed from the public marketplace.`
    );

    return res.json({ success: true, job, application });
  } catch (error: any) {
    console.error('CRITICAL: Error in accept bid route:', error);
    return res.status(500).json({ error: 'Internal server error', details: error.message });
  }
});

// Post a new job (client features)
app.post('/api/jobs', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { styleNumber, category, garmentItem, description, quantity, fobBudget, smv, colorsCount, poCount, targetDate, images, videoUrl } = req.body;
  if (!styleNumber || !category || !garmentItem || !description || !quantity || !fobBudget || !smv || !colorsCount || !poCount || !targetDate) {
    return res.status(400).json({ error: 'Missing required garment sourcing fields' });
  }

  const title = `Sourcing Style: ${styleNumber}`;
  const budget = `৳${Number(fobBudget).toFixed(2)} / pc FOB`;

  const newJob = db.saveJob({
    id: db.generateNextOrderId(),
    userId: currentUser.id,
    userName: currentUser.name,
    title,
    styleNumber,
    category,
    garmentItem,
    description,
    quantity: Number(quantity),
    budget,
    fobBudget: Number(fobBudget),
    smv: Number(smv),
    colorsCount: Number(colorsCount),
    poCount: Number(poCount),
    targetDate,
    images: images || [],
    videoUrl: videoUrl || "",
    status: 'Active',
    createdAt: new Date().toISOString()
  });

  db.addNotification(currentUser.id, `Your sourcing order for "${styleNumber}" has been posted to the marketplace successfully.`);

  res.json({ success: true, job: newJob });
});

// Apply for a job order
app.post('/api/jobs/:id/apply', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const jobId = req.params.id;
  const job = db.getJob(jobId);
  if (!job) {
    return res.status(404).json({ error: 'Job post not found' });
  }

  // Prevent applications if order is closed/filled
  if (job.status === 'Closed' || job.status === 'Filled' || (job as any).isClosed === true) {
    return res.status(400).json({ error: 'This sourcing order is closed and is no longer accepting quotations.' });
  }

  // Single-Bid Lock Constraint Check: Check if user already submitted a bid for this order
  const existingBid = db.getApplications().find(app => app.jobId === jobId && app.userId === currentUser.id);
  if (existingBid) {
    return res.status(400).json({ error: 'Single-Bid Lock: You have already applied and submitted a quotation for this sourcing order.' });
  }

  const { factoryId, priceBid, coverNote } = req.body;
  if (!factoryId || !priceBid || !coverNote) {
    return res.status(400).json({ error: 'Missing pricing bid, cover note, or factory selection' });
  }

  // Ensure selected factory belongs to the user
  const factory = db.getFactory(factoryId);
  if (!factory || factory.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden: You do not own this factory' });
  }

  const newApplication = db.saveApplication({
    id: `app-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
    jobId,
    jobTitle: job.title,
    userId: currentUser.id,
    userName: currentUser.name,
    factoryId,
    factoryName: factory.name,
    priceBid,
    coverNote,
    status: 'Pending',
    createdAt: new Date().toISOString()
  });

  // Notify job poster
  db.addNotification(job.userId, `New application received for order "${job.title}" from ${factory.name}.`);
  // Notify applicant
  db.addNotification(currentUser.id, `You applied to "${job.title}" with factory ${factory.name}.`);

  res.json({ success: true, application: newApplication });
});

// Get user applications list
app.get('/api/applications', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  res.json(db.getApplications(currentUser.id));
});

// Update application status (approve/reject bid)
app.post('/api/applications/:id/status', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { status } = req.body;
  if (!status || !['Approved', 'Rejected', 'Pending'].includes(status)) {
    return res.status(400).json({ error: 'Invalid status' });
  }

  const apps = db.getApplications();
  const application = apps.find(a => a.id === req.params.id);
  if (!application) {
    return res.status(404).json({ error: 'Application not found' });
  }

  // Check if current user is the owner of the job post
  const job = db.getJob(application.jobId);
  if (!job || job.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden: You do not own the job post for this application' });
  }

  application.status = status;
  db.saveApplication(application);

  if (status === 'Approved') {
    // Parent sourcing order model must automatically update its active status state to isClosed: true or status: "Filled"
    job.status = 'Filled';
    (job as any).isClosed = true;
    (job as any).appliedCommissionRate = db.getCommissionRate();
    (job as any).finalizedAt = new Date().toISOString();
    db.saveJob(job);

    // Reject other applications for the same job and notify them
    apps.forEach(app => {
      if (app.jobId === job.id && app.id !== application.id) {
        app.status = 'Rejected';
        db.saveApplication(app);
        db.addNotification(app.userId, `Your bid for order "${job.title}" has been closed (another supplier quote was accepted).`);
      }
    });

    // Notify accepted supplier
    db.addNotification(
      application.userId,
      `🎉 Congratulations! Your quotation of ৳${application.priceBid} for order "${job.title}" has been ACCEPTED by the buyer.`
    );

    // Notify buyer
    db.addNotification(
      currentUser.id,
      `You have accepted the quotation from "${application.factoryName}" for style "${job.styleNumber}". This order is now closed and removed from the public marketplace.`
    );
  } else {
    // Notify the applicant of other status changes (Pending / Rejected)
    db.addNotification(
      application.userId,
      `Your application for "${job.title}" has been ${status.toLowerCase()} by the buyer.`
    );
  }

  res.json({ success: true, application });
});

// --- NOTIFICATIONS ENDPOINTS ---
app.get('/api/notifications', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  res.json(db.getNotifications(currentUser.id));
});

app.post('/api/notifications/read', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  db.markNotificationsRead(currentUser.id);
  res.json({ success: true });
});

// --- NEED ORDER / CAPACITY POSTS ENDPOINTS ---

app.get('/api/capacity/all', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized: Session missing' });
  }
  const allPosts = db.getNeedOrders();
  const externalPosts = allPosts.filter(post => {
    if (post.userId === currentUser.id) return false;
    const isApprovedOrClosed = Boolean(
      post.isClosed || 
      post.quotes?.some(q => q.status === 'Approved')
    );
    if (isApprovedOrClosed) return false;
    return true;
  });
  res.json(externalPosts);
});

app.get('/api/capacity/my', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized: Session missing' });
  }
  res.json(db.getNeedOrders(currentUser.id));
});

// Get all capacity/need order posts with strict privacy controls
app.get('/api/need-orders', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized: Session missing' });
  }

  const isAdmin = currentUser.designation === 'Marketplace Admin' || currentUser.email.toLowerCase().includes('admin');
  const rawPosts = isAdmin ? db.getNeedOrders() : db.getNeedOrders(currentUser.id);

  const enrichedPosts = rawPosts.map(post => {
    const assignedUser = (post as any).assigned_staff_id
      ? (db.getUser((post as any).assigned_staff_id) || db.getUsers().find(u => u.staffId === (post as any).assigned_staff_id || u.id === (post as any).assigned_staff_id))
      : undefined;

    return {
      ...post,
      assigned_employee_code: (post as any).assigned_employee_code || (assignedUser ? (assignedUser.staffId || assignedUser.id) : null),
      assigned_employee_name: (post as any).assigned_employee_name || (assignedUser ? assignedUser.name : null),
      assigned_employee_phone: (post as any).assigned_employee_phone || (assignedUser ? assignedUser.phone : null)
    };
  });

  res.json(enrichedPosts);
});

// Create a new capacity/need order post
app.post('/api/need-orders', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const { factoryId, category, garmentItem, quantity, sewingStartDate } = req.body;
  if (!factoryId || !category || !quantity || !sewingStartDate) {
    return res.status(400).json({ error: 'Missing required need-order/capacity fields' });
  }

  // Verify factory ownership and status
  const factory = db.getFactory(factoryId);
  if (!factory) {
    return res.status(404).json({ error: 'Factory not found' });
  }
  if (factory.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden: You do not own this factory' });
  }
  if (factory.status !== 'Approved') {
    return res.status(400).json({ error: 'Only Approved factories can post capacity availability.' });
  }

  const newPost = db.saveNeedOrder({
    id: db.generateNextOrderId(),
    userId: currentUser.id,
    userName: currentUser.name,
    factoryId: factory.id,
    factoryName: factory.name,
    factoryLogo: factory.logoUrl || '',
    factoryLocation: factory.location || '',
    category,
    garmentItem: garmentItem || '',
    quantity: Number(quantity),
    sewingStartDate,
    createdAt: new Date().toISOString(),
    isClosed: false,
    quotes: []
  });

  // Notify user
  db.addNotification(currentUser.id, `Capacity availability for "${factory.name}" posted successfully! Sourcing managers can now find you under Need Order.`);

  res.json({ success: true, post: newPost });
});

// Update a capacity/need order post (CRUD)
app.put('/api/need-orders/:id', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const posts = db.getNeedOrders();
  const post = posts.find(p => p.id === req.params.id);
  if (!post) {
    return res.status(404).json({ error: 'Capacity post not found' });
  }

  if (post.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden: You do not own this capacity post' });
  }

  // Edit validation constraint lock: Block if quotes.length > 0
  if (post.quotes && post.quotes.length > 0) {
    return res.status(400).json({ error: 'Cannot modify capacity post with existing quotations.' });
  }

  const { factoryId, category, garmentItem, quantity, sewingStartDate } = req.body;
  if (!factoryId || !category || !quantity || !sewingStartDate) {
    return res.status(400).json({ error: 'Missing required need-order/capacity fields' });
  }

  // Verify factory ownership and status
  const factory = db.getFactory(factoryId);
  if (!factory) {
    return res.status(404).json({ error: 'Factory not found' });
  }
  if (factory.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden: You do not own this factory' });
  }
  if (factory.status !== 'Approved') {
    return res.status(400).json({ error: 'Only Approved factories can post capacity availability.' });
  }

  post.factoryId = factory.id;
  post.factoryName = factory.name;
  post.factoryLogo = factory.logoUrl || '';
  post.factoryLocation = factory.location || '';
  post.category = category;
  post.garmentItem = garmentItem || '';
  post.quantity = Number(quantity);
  post.sewingStartDate = sewingStartDate;

  db.saveNeedOrder(post);

  res.json({ success: true, post });
});

// Delete a capacity/need order post
app.delete('/api/need-orders/:id', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const posts = db.getNeedOrders();
  const post = posts.find(p => p.id === req.params.id);
  if (!post) {
    return res.status(404).json({ error: 'Post not found' });
  }

  if (post.userId !== currentUser.id) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  // Delete validation constraint lock: Block if quotes.length > 0
  if (post.quotes && post.quotes.length > 0) {
    return res.status(400).json({ error: 'Cannot delete capacity post with existing quotations.' });
  }

  db.deleteNeedOrder(req.params.id);
  res.json({ success: true, message: 'Need order post deleted successfully' });
});

// Accept / Assign operational ownership of a finalized capacity post (Need Order)
app.post('/api/need-orders/:id/accept', (req, res) => {
  try {
    const currentUser = (req as any).user;
    if (!currentUser) {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    const posts = db.getNeedOrders();
    const post = posts.find(p => p.id === req.params.id);
    if (!post) {
      return res.status(404).json({ error: 'Capacity post not found' });
    }

    // Must be one of the 6 executive/officer roles
    const isExecOfficer = ['Senior Executive', 'Executive', 'Junior Executive', 'Senior Officer', 'Officer', 'Junior Officer'].includes(currentUser.designation || '');
    if (!isExecOfficer) {
      return res.status(403).json({ error: 'Forbidden: Only executive/officer staff can accept assignments.' });
    }

    // Set ownership
    post.assigned_staff_id = currentUser.id;
    db.saveNeedOrder(post);

    // Send high-priority notification to the logged-in staff member
    db.addNotification(currentUser.id, `You have accepted operational tracking ownership for capacity post from "${post.factoryName}".`);

    return res.json({ success: true, post });
  } catch (err: any) {
    return res.status(500).json({ error: 'Internal server error', details: err.message });
  }
});

// Submit a sourcing proposal/quote on a capacity/need order post
app.post('/api/need-orders/:id/quotes', (req, res) => {
  const currentUser = (req as any).user;
  if (!currentUser) {
    return res.status(401).json({ error: 'Unauthorized: Session missing' });
  }

  const posts = db.getNeedOrders();
  const post = posts.find(p => p.id === req.params.id);
  if (!post) {
    return res.status(404).json({ error: 'Capacity post not found' });
  }

  if (post.userId === currentUser.id) {
    return res.status(400).json({ error: 'Cannot submit a quote on your own capacity post' });
  }

  const { category, quantity, targetBudget, styleName, smv, samplePhotos, specDescription } = req.body;
  if (!quantity || !targetBudget || !styleName || !smv || !specDescription) {
    return res.status(400).json({ error: 'Missing required proposal fields (quantity, targetBudget, styleName, smv, specDescription)' });
  }

  if (!post.quotes) {
    post.quotes = [];
  }

  // Single-Proposal Lock Constraint Check: Check if user already submitted a proposal for this capacity post
  const existingProposal = post.quotes.find(q => q.userId === currentUser.id);
  if (existingProposal) {
    return res.status(400).json({ error: 'Single-Proposal Lock: You have already submitted an inquiry or proposal for this capacity listing.' });
  }

  const newQuote = {
    id: `q-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
    userId: currentUser.id,
    userName: currentUser.name,
    category: category || post.category,
    quantity: Number(quantity),
    targetBudget: Number(targetBudget),
    styleName: String(styleName),
    smv: Number(smv),
    samplePhotos: Array.isArray(samplePhotos) ? samplePhotos.slice(0, 4) : [],
    specDescription: String(specDescription),
    status: 'Pending' as const,
    createdAt: new Date().toISOString()
  };

  post.quotes.push(newQuote);
  db.saveNeedOrder(post);

  // Notify owner
  db.addNotification(post.userId, `New sourcing proposal received for "${post.factoryName}" capacity post from "${currentUser.name}".`);

  res.json({ success: true, quote: newQuote });
});

// Approve a quote on a capacity post (single winner, sets post to isClosed: true)
app.patch('/api/need-orders/:id/quotes/:quoteId/approve', (req, res) => {
  try {
    const currentUser = (req as any).user;
    if (!currentUser) {
      return res.status(401).json({ error: 'Unauthorized' });
    }

    const posts = db.getNeedOrders();
    const post = posts.find(p => p.id === req.params.id);
    if (!post) {
      return res.status(404).json({ error: 'Capacity post not found' });
    }

    if (post.userId !== currentUser.id) {
      return res.status(403).json({ error: 'Forbidden: You do not own this capacity post' });
    }

    if (!post.quotes) {
      post.quotes = [];
    }

    const quote = post.quotes.find(q => q.id === req.params.quoteId);
    if (!quote) {
      return res.status(404).json({ error: 'Quote not found' });
    }

    // Update quote status: Approved for this one, Rejected for the others
    post.quotes.forEach(q => {
      if (q.id === quote.id) {
        q.status = 'Approved';
      } else {
        q.status = 'Rejected';
      }
    });

    // Set the capacity post itself to isClosed: true
    post.isClosed = true;
    (post as any).appliedCommissionRate = db.getCommissionRate();
    (post as any).finalizedAt = new Date().toISOString();

    db.saveNeedOrder(post);

    // Notify the approved buyer
    db.addNotification(quote.userId, `Congratulations! Your sourcing proposal for "${post.factoryName || 'Factory'}" has been APPROVED by the factory owner.`);

    return res.json({ success: true, post });
  } catch (error: any) {
    console.error('CRITICAL: Error in capacity quote approve route:', error);
    return res.status(500).json({ error: 'Internal server error', details: error.message });
  }
});

// --- ACI SECTION ENDPOINTS ---

// Get video ad spots
app.get('/api/aci/ads', (req, res) => {
  try {
    const ads = db.getAciAds();
    return res.json(ads);
  } catch (error: any) {
    console.error('Error fetching ACI ads:', error);
    return res.status(500).json({ error: error.message });
  }
});

// Update video ad spot (Admin only)
app.post('/api/aci/ads', requireAdmin, (req, res) => {
  try {
    const { id, spotNumber, title, videoUrl, thumbnailUrl, caption, isActive } = req.body;
    if (!spotNumber || !title || !videoUrl) {
      return res.status(400).json({ error: 'spotNumber, title, and videoUrl are required' });
    }
    const adObj = {
      id: id || `spot-${spotNumber}`,
      spotNumber: Number(spotNumber),
      title,
      videoUrl,
      thumbnailUrl,
      caption,
      isActive: isActive !== false,
      updatedAt: new Date().toISOString()
    };
    const saved = db.saveAciAd(adObj);
    return res.json({ success: true, ad: saved, ads: db.getAciAds() });
  } catch (error: any) {
    console.error('Error saving ACI ad:', error);
    return res.status(500).json({ error: error.message });
  }
});

// Get Garment Categories & Items
app.get('/api/aci/categories', (req, res) => {
  try {
    const categories = db.getAciCategoriesList();
    const items = db.getAciItemsList();
    const catalog = db.getAciCategories();
    return res.json({ categories, items, catalog });
  } catch (error: any) {
    console.error('Error fetching ACI categories:', error);
    return res.status(500).json({ error: error.message });
  }
});

// Save/Update Garment Category (Admin only)
app.post('/api/aci/categories', requireAdmin, (req, res) => {
  try {
    const { id, name, category, item, code, description, status } = req.body;
    // Handle category name from name or category field
    const catName = name || category;
    if (!catName) {
      return res.status(400).json({ error: 'Category Name is required' });
    }
    const catObj = {
      id,
      name: catName,
      code,
      description,
      status: status || 'Active',
      createdAt: new Date().toISOString()
    };
    const saved = db.saveAciCategory(catObj);
    return res.json({ 
      success: true, 
      category: saved, 
      categories: db.getAciCategoriesList(), 
      items: db.getAciItemsList() 
    });
  } catch (error: any) {
    console.error('Error saving ACI category:', error);
    return res.status(500).json({ error: error.message });
  }
});

// Delete Garment Category (Admin only)
app.delete('/api/aci/categories/:id', requireAdmin, (req, res) => {
  try {
    const deleted = db.deleteAciCategory(req.params.id);
    if (!deleted) {
      db.deleteAciCategoryItem(req.params.id);
    }
    return res.json({ 
      success: true, 
      categories: db.getAciCategoriesList(), 
      items: db.getAciItemsList() 
    });
  } catch (error: any) {
    console.error('Error deleting ACI category:', error);
    return res.status(500).json({ error: error.message });
  }
});

// Save/Update Garment Item (Admin only)
app.post('/api/aci/items', requireAdmin, (req, res) => {
  try {
    const { id, category, name, item, code, description, status } = req.body;
    const itemName = name || item;
    if (!category || !itemName) {
      return res.status(400).json({ error: 'Category and Item Name are required' });
    }
    const itemObj = {
      id,
      category,
      name: itemName,
      code,
      description,
      status: status || 'Active',
      createdAt: new Date().toISOString()
    };
    const saved = db.saveAciItem(itemObj);
    return res.json({ 
      success: true, 
      item: saved, 
      categories: db.getAciCategoriesList(), 
      items: db.getAciItemsList() 
    });
  } catch (error: any) {
    console.error('Error saving ACI item:', error);
    return res.status(500).json({ error: error.message });
  }
});

// Delete Garment Item (Admin only)
app.delete('/api/aci/items/:id', requireAdmin, (req, res) => {
  try {
    const deleted = db.deleteAciItem(req.params.id);
    return res.json({ 
      success: true, 
      categories: db.getAciCategoriesList(), 
      items: db.getAciItemsList() 
    });
  } catch (error: any) {
    console.error('Error deleting ACI item:', error);
    return res.status(500).json({ error: error.message });
  }
});



// Error handling middleware for API routes to always return JSON instead of HTML
app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
  if (req.path.startsWith('/api')) {
    console.error('API Error:', err);
    return res.status(err.status || 500).json({
      error: err.message || 'Internal Server Error'
    });
  }
  next(err);
});

// --- VITE MIDDLEWARE SETUP ---

async function startServer() {
  if (process.env.NODE_ENV !== "production") {
    const vite = await createViteServer({
      server: { middlewareMode: true },
      appType: "spa",
    });
    app.use(vite.middlewares);
  } else {
    const distPath = path.join(process.cwd(), 'dist');
    app.use(express.static(distPath));
    app.get('*', (req, res) => {
      res.sendFile(path.join(distPath, 'index.html'));
    });
  }

  app.listen(PORT, "0.0.0.0", () => {
    console.log(`B2B Garments Marketplace Server running on http://localhost:${PORT}`);
  });
}

startServer();
