/**
 * Form 16 permission service – API-driven access based on admin configuration.
 * Reads submissionViewerEmails and twentySixAsViewerEmails from FORM16_ADMIN_CONFIG.
 * No hardcoded emails or roles; all driven by stored config.
 */

import { sequelize } from '../config/database';
import { QueryTypes } from 'sequelize';
import { getDealerCodeForUser } from './form16.service';

const FORM16_CONFIG_KEY = 'FORM16_ADMIN_CONFIG';

export interface Form16ViewerConfig {
  submissionViewerEmails: string[];
  twentySixAsViewerEmails: string[];
}

const emptyConfig: Form16ViewerConfig = {
  submissionViewerEmails: [],
  twentySixAsViewerEmails: [],
};

/** Normalize email for comparison (lowercase, trim). */
function normalizeEmail(email: string): string {
  return (email || '').trim().toLowerCase();
}

/**
 * Load Form 16 viewer config from admin_configurations (API-driven).
 * Returns empty arrays if no config or parse error.
 */
export async function getForm16ViewerConfig(): Promise<Form16ViewerConfig> {
  try {
    const result = await sequelize.query<{ config_value: string }>(
      `SELECT config_value FROM admin_configurations WHERE config_key = :configKey LIMIT 1`,
      { replacements: { configKey: FORM16_CONFIG_KEY }, type: QueryTypes.SELECT }
    );
    if (!result?.length || !result[0].config_value) {
      return emptyConfig;
    }
    const parsed = JSON.parse(result[0].config_value);
    const submission = Array.isArray(parsed.submissionViewerEmails)
      ? parsed.submissionViewerEmails.map((e: unknown) => normalizeEmail(String(e ?? ''))).filter(Boolean)
      : [];
    const twentySixAs = Array.isArray(parsed.twentySixAsViewerEmails)
      ? parsed.twentySixAsViewerEmails.map((e: unknown) => normalizeEmail(String(e ?? ''))).filter(Boolean)
      : [];
    return { submissionViewerEmails: submission, twentySixAsViewerEmails: twentySixAs };
  } catch {
    return emptyConfig;
  }
}

/**
 * Check if user can view Form 16 submission data (Credit Notes, Non-submitted Dealers, etc.).
 * - Admin: always allowed (full access to everything).
 * - Dealers: always allowed (they see their own submissions).
 * - RE users: allowed only if user email is in submissionViewerEmails
 *   OR in twentySixAsViewerEmails (26AS access implies submission access).
 */
export async function canViewForm16Submission(
  userEmail: string,
  userId: string,
  role?: string
): Promise<boolean> {
  if (role === 'ADMIN') return true;
  const isDealer = (await getDealerCodeForUser(userId)) !== null;
  if (isDealer) return true;
  const config = await getForm16ViewerConfig();
  const email = normalizeEmail(userEmail);
  if (!email) return false;
  if (config.submissionViewerEmails.includes(email)) return true;
  if (config.twentySixAsViewerEmails.includes(email)) return true;
  return false;
}

/**
 * Check if user can view 26AS page and 26AS data.
 * - Admin: always allowed (full access to everything).
 * - Otherwise: allowed only if user email is in twentySixAsViewerEmails.
 */
export async function canView26As(userEmail: string, role?: string): Promise<boolean> {
  if (role === 'ADMIN') return true;
  const config = await getForm16ViewerConfig();
  const email = normalizeEmail(userEmail);
  if (!email) return false;
  return config.twentySixAsViewerEmails.includes(email);
}
