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

// ─── Admin: Statements ───────────────────────────────────────────────────────

export const createStatement = async (req: Request, res: Response): Promise<void> => {
  try {
    const { statement_text, dimension, direction, sequence } = req.body;
    if (!statement_text || !dimension || !direction) {
      sendResponse(res, 400, 'statement_text, dimension, and direction are required');
      return;
    }
    const statement = await psychometricService.createStatement({ statement_text, dimension, direction, sequence });
    sendResponse(res, 201, 'Statement created', { statement });
  } catch (error) { handleError(res, error); }
};

export const getAllStatements = async (req: Request, res: Response): Promise<void> => {
  try {
    const page = Math.max(1, parseInt(req.query.page as string) || 1);
    const limit = Math.min(100, Math.max(1, parseInt(req.query.limit as string) || 20));
    const dimension = req.query.dimension as string | undefined;
    const { statements, pagination } = await psychometricService.getAllStatements(page, limit, dimension) as { statements: unknown; pagination: Record<string, unknown> };
    sendResponse(res, 200, 'Statements fetched', { statements }, pagination);
  } catch (error) { handleError(res, error); }
};

export const getStatement = async (req: Request, res: Response): Promise<void> => {
  try {
    const statement = await psychometricService.getStatementById(req.params.id as string);
    sendResponse(res, 200, 'Statement fetched', { statement });
  } catch (error) { handleError(res, error); }
};

export const updateStatement = async (req: Request, res: Response): Promise<void> => {
  try {
    const statement = await psychometricService.updateStatement(req.params.id as string, req.body);
    sendResponse(res, 200, 'Statement updated', { statement });
  } catch (error) { handleError(res, error); }
};

export const deleteStatement = async (req: Request, res: Response): Promise<void> => {
  try {
    await psychometricService.deleteStatement(req.params.id as string);
    sendResponse(res, 200, 'Statement deleted');
  } catch (error) { handleError(res, error); }
};

// ─── Admin: Tests ────────────────────────────────────────────────────────────

export const createTest = async (req: Request, res: Response): Promise<void> => {
  try {
    const { title, description, statements, status } = req.body;
    if (!title || !statements) {
      sendResponse(res, 400, 'title and statements are required');
      return;
    }
    const test = await psychometricService.createTest({ title, description, statements, status });
    sendResponse(res, 201, 'Test created', { test });
  } catch (error) { handleError(res, error); }
};

export const getAllTests = async (req: Request, res: Response): Promise<void> => {
  try {
    const page = Math.max(1, parseInt(req.query.page as string) || 1);
    const limit = Math.min(100, Math.max(1, parseInt(req.query.limit as string) || 10));
    const status = req.query.status as string | undefined;
    const { tests, pagination } = await psychometricService.getAllTests(status, page, limit) as { tests: unknown; pagination: Record<string, unknown> };
    sendResponse(res, 200, 'Tests fetched', { tests }, pagination);
  } catch (error) { handleError(res, error); }
};

export const getTest = async (req: Request, res: Response): Promise<void> => {
  try {
    const test = await psychometricService.getTestById(req.params.id as string);
    sendResponse(res, 200, 'Test fetched', { test });
  } catch (error) { handleError(res, error); }
};

export const updateTest = async (req: Request, res: Response): Promise<void> => {
  try {
    const test = await psychometricService.updateTest(req.params.id as string, req.body);
    sendResponse(res, 200, 'Test updated', { test });
  } catch (error) { handleError(res, error); }
};

export const deleteTest = async (req: Request, res: Response): Promise<void> => {
  try {
    await psychometricService.deleteTest(req.params.id as string);
    sendResponse(res, 200, 'Test deleted');
  } catch (error) { handleError(res, error); }
};

export const getTestResults = async (req: Request, res: Response): Promise<void> => {
  try {
    const { test, results } = await psychometricService.getTestResults(req.params.id as string);
    sendResponse(res, 200, 'Test results fetched', { test, count: results.length, results });
  } catch (error) { handleError(res, error); }
};

export const getUserResult = async (req: Request, res: Response): Promise<void> => {
  try {
    const result = await psychometricService.getUserResult(req.params.testId as string, req.params.userId as string);
    sendResponse(res, 200, 'User result fetched', { result });
  } catch (error) { handleError(res, error); }
};

// ─── User ────────────────────────────────────────────────────────────────────

export const getActiveTests = async (req: Request, res: Response): Promise<void> => {
  try {
    const tests = await psychometricService.getActiveTests(req.user!.id);
    sendResponse(res, 200, 'Active tests fetched', { tests });
  } catch (error) { handleError(res, error); }
};

export const attemptTest = async (req: Request, res: Response): Promise<void> => {
  try {
    const result = await psychometricService.attemptTest(req.params.id as string, req.user!.id);
    sendResponse(res, 200, 'Test attempt fetched', result);
  } catch (error) { handleError(res, error); }
};

export const submitTest = async (req: Request, res: Response): Promise<void> => {
  try {
    const { responses } = req.body;
    if (!responses || !Array.isArray(responses) || responses.length === 0) {
      sendResponse(res, 400, 'responses array is required');
      return;
    }
    const result = await psychometricService.submitTest(req.params.id as string, req.user!.id, responses);
    sendResponse(res, 201, 'Test submitted successfully', { profile: result.profile, personality_type: result.personality_type });
  } catch (error) { handleError(res, error); }
};

export const getMyResults = async (req: Request, res: Response): Promise<void> => {
  try {
    const results = await psychometricService.getMyResults(req.user!.id);
    sendResponse(res, 200, 'Results fetched', { results });
  } catch (error) { handleError(res, error); }
};
