import express, { Request, Response, NextFunction } from 'express';
import crypto from 'crypto';
import fs from 'fs';
import path from 'path';
import { db, verifyPassword } from './db.js';
import type { Role } from '../src/types.js';

export const router = express.Router();

// Middleware to extract and verify the signed Authorization token
interface AuthRequest extends Request {
  user?: {
    id: string;
    email: string;
    role: Role;
    name: string;
  };
}

const authenticate = (req: AuthRequest, res: Response, next: NextFunction) => {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return next();
  }

  const token = authHeader.split(' ')[1];
  try {
    const [payloadPart, signature] = token.split('.');
    if (!payloadPart || !signature) return next();
    const secret = process.env.ZANASHOP_AUTH_SECRET || 'dev-only-change-this-secret';
    const expected = crypto.createHmac('sha256', secret).update(payloadPart).digest('base64url');
    if (signature.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) return next();
    const decoded = JSON.parse(Buffer.from(payloadPart, 'base64url').toString('utf-8'));
    if (decoded?.exp && Date.now() > decoded.exp) return next();
    if (decoded && decoded.id) {
      const user = db.getUserById(decoded.id);
      if (user && user.isActive) {
        req.user = { id: user.id, email: user.email, role: user.role, name: user.name };
      }
    }
  } catch {
    // invalid token, proceed unauthenticated
  }
  next();
};

const requireAuth = (req: AuthRequest, res: Response, next: NextFunction) => {
  if (!req.user) {
    return res.status(401).json({ error: 'لطفاً ابتدا وارد حساب کاربری خود شوید' });
  }
  next();
};

const requireAdmin = (req: AuthRequest, res: Response, next: NextFunction) => {
  if (!req.user || req.user.role !== 'admin') {
    return res.status(403).json({ error: 'شما دسترسی لازم برای انجام این عملیات (مدیریت) را ندارید' });
  }
  next();
};

router.use(authenticate);


const TUTORIALS_FILE = path.join(process.cwd(), 'data', 'tutorials.json');

interface TutorialRecord {
  id: string;
  title: string;
  platform: 'Windows' | 'Android' | 'iOS';
  description: string;
  aparatUrl: string;
  embedUrl?: string;
  thumbnail?: string;
  active: boolean;
  createdAt: string;
  updatedAt?: string;
}

function readTutorials(): TutorialRecord[] {
  try {
    if (!fs.existsSync(TUTORIALS_FILE)) return [];
    return JSON.parse(fs.readFileSync(TUTORIALS_FILE, 'utf8')) as TutorialRecord[];
  } catch { return []; }
}
function writeTutorials(items: TutorialRecord[]) {
  fs.mkdirSync(path.dirname(TUTORIALS_FILE), { recursive: true });
  const tmp = `${TUTORIALS_FILE}.tmp`;
  fs.writeFileSync(tmp, JSON.stringify(items, null, 2), 'utf8');
  fs.renameSync(tmp, TUTORIALS_FILE);
}

// --- TUTORIALS ---
router.get('/tutorials', (req: Request, res: Response) => {
  const items = readTutorials();
  return res.json(req.query.all === 'true' ? items : items.filter(t => t.active));
});

router.post('/tutorials', requireAdmin, (req: Request, res: Response) => {
  const { title, platform, description, aparatUrl, embedUrl, thumbnail, active } = req.body;
  if (!title || !platform) return res.status(400).json({ error: 'عنوان و پلتفرم آموزش الزامی است' });
  const items = readTutorials();
  const item: TutorialRecord = {
    id: `tutorial_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`,
    title: String(title).trim(), platform, description: String(description || '').trim(),
    aparatUrl: String(aparatUrl || '').trim(), embedUrl: String(embedUrl || '').trim(),
    thumbnail: String(thumbnail || '').trim(), active: active !== false, createdAt: new Date().toISOString()
  };
  items.push(item); writeTutorials(items); return res.status(201).json(item);
});

router.put('/tutorials/:id', requireAdmin, (req: Request, res: Response) => {
  const items = readTutorials(); const idx = items.findIndex(t => t.id === req.params.id);
  if (idx < 0) return res.status(404).json({ error: 'آموزش یافت نشد' });
  items[idx] = { ...items[idx], ...req.body, id: items[idx].id, updatedAt: new Date().toISOString() };
  writeTutorials(items); return res.json(items[idx]);
});

router.delete('/tutorials/:id', requireAdmin, (req: Request, res: Response) => {
  const items = readTutorials(); const next = items.filter(t => t.id !== req.params.id);
  if (next.length === items.length) return res.status(404).json({ error: 'آموزش یافت نشد' });
  writeTutorials(next); return res.json({ message: 'آموزش حذف شد' });
});


// --- AUTH ROUTES ---

router.post('/auth/register', (req: Request, res: Response) => {
  try {
    const { name, email, mobile, password } = req.body;
    if (!name || !email || !password) {
      return res.status(400).json({ error: 'نام، ایمیل و رمز عبور الزامی هستند' });
    }
    if (password.length < 6) {
      return res.status(400).json({ error: 'رمز عبور باید حداقل ۶ کاراکتر باشد' });
    }

    const user = db.createUser(name, email, mobile || '', password, 'user');
    const token = (() => { const secret = process.env.ZANASHOP_AUTH_SECRET || 'dev-only-change-this-secret'; const payload = Buffer.from(JSON.stringify({ id: user.id, email: user.email, role: user.role, exp: Date.now() + 1000 * 60 * 60 * 24 * 7 })).toString('base64url'); const sig = crypto.createHmac('sha256', secret).update(payload).digest('base64url'); return `${payload}.${sig}`; })();

    return res.json({
      message: 'ثبت‌نام با موفقیت انجام شد',
      user,
      token,
    });
  } catch (err: any) {
    return res.status(400).json({ error: err.message || 'خطا در ثبت‌نام' });
  }
});

router.post('/auth/login', (req: Request, res: Response) => {
  try {
    const { email, password } = req.body;
    if (!email || !password) {
      return res.status(400).json({ error: 'ایمیل و رمز عبور را وارد کنید' });
    }

    const userInDb = db.getUserByEmail(email);
    if (!userInDb || !verifyPassword(password, userInDb.passwordHash, userInDb.salt)) {
      return res.status(400).json({ error: 'ایمیل یا رمز عبور اشتباه است' });
    }

    if (!userInDb.isActive) {
      return res.status(403).json({ error: 'حساب کاربری شما غیرفعال شده است' });
    }

    const { passwordHash, salt, ...safeUser } = userInDb;
    const token = (() => { const secret = process.env.ZANASHOP_AUTH_SECRET || 'dev-only-change-this-secret'; const payload = Buffer.from(JSON.stringify({ id: userInDb.id, email: userInDb.email, role: userInDb.role, exp: Date.now() + 1000 * 60 * 60 * 24 * 7 })).toString('base64url'); const sig = crypto.createHmac('sha256', secret).update(payload).digest('base64url'); return `${payload}.${sig}`; })();

    return res.json({
      message: 'ورود موفقیت‌آمیز بود',
      user: safeUser,
      token,
    });
  } catch (err: any) {
    return res.status(500).json({ error: err.message || 'خطا در ورود' });
  }
});

router.get('/auth/me', (req: AuthRequest, res: Response) => {
  if (!req.user) {
    return res.status(401).json({ error: 'کاربر وارد نشده است' });
  }
  const user = db.getUserById(req.user.id);
  if (!user) {
    return res.status(404).json({ error: 'کاربر یافت نشد' });
  }
  return res.json({ user });
});

// --- CATEGORIES ROUTES ---

router.get('/categories', (req: Request, res: Response) => {
  try {
    const onlyActive = req.query.all !== 'true';
    const categories = db.getCategories(onlyActive);
    return res.json(categories);
  } catch (err: any) {
    return res.status(500).json({ error: err.message });
  }
});

router.post('/categories', requireAdmin, (req: Request, res: Response) => {
  try {
    const { name, slug, icon, description, isActive, sortOrder } = req.body;
    if (!name) {
      return res.status(400).json({ error: 'نام دسته‌بندی الزامی است' });
    }
    const cat = db.createCategory({
      name,
      slug: slug || name.toLowerCase().replace(/\s+/g, '-'),
      icon: icon || 'Folder',
      description,
      isActive: isActive !== undefined ? Boolean(isActive) : true,
      sortOrder: Number(sortOrder) || 1,
    });
    return res.status(201).json(cat);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

router.put('/categories/:id', requireAdmin, (req: Request, res: Response) => {
  try {
    const updated = db.updateCategory(req.params.id, req.body);
    return res.json(updated);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

router.delete('/categories/:id', requireAdmin, (req: Request, res: Response) => {
  try {
    db.deleteCategory(req.params.id);
    return res.json({ message: 'دسته‌بندی با موفقیت حذف شد' });
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

// --- PRODUCTS ROUTES ---

router.get('/products', (req: Request, res: Response) => {
  try {
    const { category, search, sort, isFeatured, minPrice, maxPrice, all } = req.query;
    const products = db.getProducts({
      categoryId: category as string,
      search: search as string,
      sort: sort as string,
      isFeatured: isFeatured === 'true',
      minPrice: minPrice ? Number(minPrice) : undefined,
      maxPrice: maxPrice ? Number(maxPrice) : undefined,
      onlyActive: all !== 'true',
    });
    return res.json(products);
  } catch (err: any) {
    return res.status(500).json({ error: err.message });
  }
});

router.get('/products/:idOrSlug', (req: Request, res: Response) => {
  try {
    const product = db.getProductById(req.params.idOrSlug);
    if (!product) {
      return res.status(404).json({ error: 'محصول یافت نشد' });
    }
    return res.json(product);
  } catch (err: any) {
    return res.status(500).json({ error: err.message });
  }
});

router.post('/products', requireAdmin, (req: Request, res: Response) => {
  try {
    const { title, slug, categoryId, price, originalPrice, discountPercent, description, features, tags, image, badge, inStock, stockCount, isFeatured, isBestSeller, platform, regions, deliveryType, deliveryNote } = req.body;
    
    if (!title || !categoryId || price === undefined) {
      return res.status(400).json({ error: 'عنوان، دسته‌بندی و قیمت الزامی هستند' });
    }

    const product = db.createProduct({
      title,
      slug,
      categoryId,
      price: Number(price),
      originalPrice: originalPrice ? Number(originalPrice) : undefined,
      discountPercent: discountPercent ? Number(discountPercent) : undefined,
      description: description || '',
      features: features || [],
      tags: tags || [],
      image: image || '',
      badge: badge || '',
      inStock: inStock !== undefined ? Boolean(inStock) : true,
      stockCount: Number(stockCount) || 10,
      isFeatured: Boolean(isFeatured),
      isBestSeller: Boolean(isBestSeller),
      platform: platform || undefined,
      regions: Array.isArray(regions) ? regions : [],
      deliveryType: deliveryType || 'instant_code',
      deliveryNote: deliveryNote || '',
    });

    return res.status(201).json(product);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

router.put('/products/:id', requireAdmin, (req: Request, res: Response) => {
  try {
    const updated = db.updateProduct(req.params.id, req.body);
    return res.json(updated);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

router.delete('/products/:id', requireAdmin, (req: Request, res: Response) => {
  try {
    db.deleteProduct(req.params.id);
    return res.json({ message: 'محصول با موفقیت حذف شد' });
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

// --- COUPONS ROUTES ---

router.post('/coupons/validate', (req: Request, res: Response) => {
  try {
    const { code, subtotal } = req.body;
    if (!code) {
      return res.status(400).json({ valid: false, message: 'کد تخفیف را وارد کنید' });
    }
    const result = db.validateCoupon(code, Number(subtotal) || 0);
    return res.json(result);
  } catch (err: any) {
    return res.status(500).json({ valid: false, message: err.message });
  }
});

router.get('/coupons', requireAdmin, (req: Request, res: Response) => {
  try {
    const coupons = db.getCoupons();
    return res.json(coupons);
  } catch (err: any) {
    return res.status(500).json({ error: err.message });
  }
});

router.post('/coupons', requireAdmin, (req: Request, res: Response) => {
  try {
    const { code, discountType, discountValue, minPurchase, maxDiscount, maxUses, isActive, startDate, endDate } = req.body;
    if (!code || !discountValue) {
      return res.status(400).json({ error: 'کد و مقدار تخفیف الزامی است' });
    }
    const coupon = db.createCoupon({
      code,
      discountType: discountType || 'percent',
      discountValue: Number(discountValue),
      minPurchase: Number(minPurchase) || 0,
      maxDiscount: maxDiscount ? Number(maxDiscount) : undefined,
      maxUses: Number(maxUses) || 100,
      isActive: isActive !== undefined ? Boolean(isActive) : true,
      startDate,
      endDate,
    });
    return res.status(201).json(coupon);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

router.put('/coupons/:id', requireAdmin, (req: Request, res: Response) => {
  try {
    const updated = db.updateCoupon(req.params.id, req.body);
    return res.json(updated);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

router.delete('/coupons/:id', requireAdmin, (req: Request, res: Response) => {
  try {
    db.deleteCoupon(req.params.id);
    return res.json({ message: 'کد تخفیف حذف شد' });
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

// --- ORDERS ROUTES ---

router.post('/orders', (req: AuthRequest, res: Response) => {
  try {
    const { guestInfo, items, couponCode, paymentMethod } = req.body;
    if (!items || items.length === 0) {
      return res.status(400).json({ error: 'سبد خرید خالی است' });
    }
    if (!guestInfo || !guestInfo.name || !guestInfo.mobile) {
      return res.status(400).json({ error: 'نام و شماره تماس الزامی هستند' });
    }

    const order = db.createOrder({
      userId: req.user?.id,
      guestInfo,
      items,
      couponCode,
      paymentMethod: paymentMethod || 'online_gateway',
    });

    return res.status(201).json(order);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

router.get('/orders', (req: AuthRequest, res: Response) => {
  try {
    if (req.user?.role === 'admin') {
      const orders = db.getOrders({ status: req.query.status as string });
      return res.json(orders);
    } else if (req.user) {
      const orders = db.getOrders({ userId: req.user.id });
      return res.json(orders);
    } else {
      return res.status(401).json({ error: 'لطفاً وارد شوید' });
    }
  } catch (err: any) {
    return res.status(500).json({ error: err.message });
  }
});

router.get('/orders/:idOrNumber', (req: Request, res: Response) => {
  try {
    const order = db.getOrderById(req.params.idOrNumber);
    if (!order) {
      return res.status(404).json({ error: 'سفارش پیدا نشد' });
    }
    return res.json(order);
  } catch (err: any) {
    return res.status(500).json({ error: err.message });
  }
});

router.patch('/orders/:id/status', requireAdmin, (req: Request, res: Response) => {
  try {
    const { orderStatus, paymentStatus, licenseKeys, deliveryInstructions } = req.body;
    const updated = db.updateOrderStatus(req.params.id, {
      orderStatus,
      paymentStatus,
      licenseKeys,
      deliveryInstructions,
    });
    return res.json(updated);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});

// --- ADMIN DASHBOARD & USERS ---

router.get('/admin/stats', requireAdmin, (req: Request, res: Response) => {
  try {
    const stats = db.getDashboardStats();
    return res.json(stats);
  } catch (err: any) {
    return res.status(500).json({ error: err.message });
  }
});

router.get('/admin/users', requireAdmin, (req: Request, res: Response) => {
  try {
    const users = db.getUsers();
    return res.json(users);
  } catch (err: any) {
    return res.status(500).json({ error: err.message });
  }
});

router.patch('/admin/users/:id', requireAdmin, (req: Request, res: Response) => {
  try {
    const { role, isActive, name, mobile } = req.body;
    const updated = db.updateUser(req.params.id, {
      role,
      isActive,
      name,
      mobile,
    });
    return res.json(updated);
  } catch (err: any) {
    return res.status(400).json({ error: err.message });
  }
});
