import { Request, Response } from 'express';
import fs from 'fs';
import * as desktopReleaseService from '../services/desktopReleaseService';
import { sendResponse, handleError } from '../utils/apiResponse';

const buildDownloadUrl = (req: Request, fileName: string): string => {
  // Must point at this API's own origin, not a frontend URL (ADMIN_URL/USER_URL/URL) -
  // those apps don't have a /downloads route and will just redirect/404 client-side.
  const base = process.env.API_URL?.replace(/\/+$/, '') || `${req.protocol}://${req.get('host')}`;
  return `${base}/downloads/${encodeURIComponent(fileName)}`;
};

// @desc    Upload a new desktop release
// @route   POST /api/admin/desktop-release
export const uploadDesktopRelease = async (req: Request, res: Response): Promise<void> => {
  try {
    const release = await desktopReleaseService.createDesktopRelease(req.body, req.file);
    sendResponse(res, 201, 'Desktop release uploaded', {
      ...release.toObject(),
      download_url: buildDownloadUrl(req, release.installer_filename),
    });
  } catch (error) {
    handleError(res, error);
  }
};

// @desc    List all desktop releases
// @route   GET /api/admin/desktop-release
export const listDesktopReleases = async (req: Request, res: Response): Promise<void> => {
  try {
    const releases = await desktopReleaseService.getAllDesktopReleases();
    const withUrls = releases.map((release) => ({
      ...release,
      download_url: buildDownloadUrl(req, release.installer_filename),
    }));
    sendResponse(res, 200, 'Desktop releases fetched', { count: withUrls.length, releases: withUrls });
  } catch (error) {
    handleError(res, error);
  }
};

// @desc    Delete a desktop release
// @route   DELETE /api/admin/desktop-release/:id
export const removeDesktopRelease = async (req: Request, res: Response): Promise<void> => {
  try {
    await desktopReleaseService.deleteDesktopRelease(String(req.params.id));
    sendResponse(res, 200, 'Desktop release deleted');
  } catch (error) {
    handleError(res, error);
  }
};

// @desc    Get the latest active desktop version
// @route   GET /api/desktop/latest-version
export const getLatestDesktopVersion = async (req: Request, res: Response): Promise<void> => {
  try {
    const release = await desktopReleaseService.getLatestActiveDesktopRelease(req.query.platform);
    res.status(200).json({
      success: true,
      platform: release.platform,
      version: release.version,
      mandatory: release.mandatory,
      release_notes: release.release_notes,
      download_url: buildDownloadUrl(req, release.installer_filename),
    });
  } catch (error) {
    const e = error as Error & { statusCode?: number };
    res.status(e.statusCode || 500).json({ success: false, message: e.message || 'Something went wrong' });
  }
};

// @desc    Download an installer file
// @route   GET /downloads/:fileName
export const downloadInstaller = (req: Request, res: Response): void => {
  try {
    const fileName = String(req.params.fileName);
    const filePath = desktopReleaseService.resolveInstallerPath(fileName);
    if (!fs.existsSync(filePath)) {
      res.status(404).json({ success: false, message: 'File not found' });
      return;
    }
    res.set('Cross-Origin-Resource-Policy', 'cross-origin');
    res.download(filePath, fileName);
  } catch (error) {
    const e = error as Error & { statusCode?: number };
    res.status(e.statusCode || 500).json({ success: false, message: e.message || 'Something went wrong' });
  }
};
