import { Request, Response, NextFunction } from 'express'
import jwt from 'jsonwebtoken'
import type { AuthUser, ApiResponse } from '../types/index.js'

const JWT_SECRET = process.env.JWT_SECRET || 'default-secret'

export interface AuthRequest extends Request {
  user?: AuthUser
}

export function generateToken(user: AuthUser): string {
  return jwt.sign(user, JWT_SECRET, { expiresIn: '7d' })
}

export function authMiddleware(req: AuthRequest, res: Response, next: NextFunction) {
  const authHeader = req.headers.authorization
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    const response: ApiResponse = { success: false, data: null, error: 'No token provided' }
    return res.status(401).json(response)
  }

  const token = authHeader.substring(7)
  try {
    const decoded = jwt.verify(token, JWT_SECRET) as AuthUser
    req.user = decoded
    next()
  } catch {
    const response: ApiResponse = { success: false, data: null, error: 'Invalid or expired token' }
    return res.status(401).json(response)
  }
}

export function requireRole(...roles: string[]) {
  return (req: AuthRequest, res: Response, next: NextFunction) => {
    if (!req.user) {
      const response: ApiResponse = { success: false, data: null, error: 'Not authenticated' }
      return res.status(401).json(response)
    }
    if (!roles.includes(req.user.role)) {
      const response: ApiResponse = { success: false, data: null, error: 'Insufficient permissions' }
      return res.status(403).json(response)
    }
    next()
  }
}

export function requireStoreAccess(req: AuthRequest, res: Response, next: NextFunction) {
  if (!req.user) {
    const response: ApiResponse = { success: false, data: null, error: 'Not authenticated' }
    return res.status(401).json(response)
  }
  if (req.user.role === 'hq' || req.user.role === 'dept') {
    return next()
  }
  if (req.user.role === 'store') {
    const storeCode = req.params.code || req.params.storeCode || req.body.store_code
    if (storeCode && storeCode !== req.user.storeCode) {
      const response: ApiResponse = { success: false, data: null, error: 'Access denied to this store' }
      return res.status(403).json(response)
    }
  }
  next()
}
