import {settingsRepository} from '@/features/settings/repositories/settingsRepository';
import type {MerchantProfile} from '@/features/settings/types/settings';

/**
 * Domain rules for the settings module.
 *
 * The validation lives here rather than in the form for the same reason the
 * login rules live in authService: a rule that only exists inside a component
 * cannot be reused by a second screen, cannot be unit-tested without mounting
 * React, and quietly disappears the day the screen is redesigned.
 */

export type ProfileFieldErrors = Partial<Record<keyof MerchantProfile, string>>;

export function validateProfile(profile: MerchantProfile): ProfileFieldErrors {
  const errors: ProfileFieldErrors = {};
  if (!profile.businessName.trim()) {
    errors.businessName = 'Business name is required';
  }
  if (!/^\S+@\S+\.\S+$/.test(profile.email)) {
    errors.email = 'Enter a valid email address';
  }
  // Optional, but a partial GSTIN is worse than none — it will fail at
  // settlement time rather than here.
  if (profile.gstin && profile.gstin.length !== 15) {
    errors.gstin = 'GSTIN is 15 characters';
  }
  return errors;
}

export const settingsService = {
  validateProfile,

  /**
   * Validate, then save. Returns the field errors rather than throwing —
   * invalid input is an expected outcome of a form submission, not an
   * exception, and the caller has to render them either way.
   */
  async saveProfile(
    profile: MerchantProfile,
  ): Promise<{ok: true} | {ok: false; errors: ProfileFieldErrors; message?: string}> {
    const errors = validateProfile(profile);
    if (Object.keys(errors).length > 0) return {ok: false, errors};

    const res = await settingsRepository.updateProfile(profile);
    if (!res.ok) {
      return {
        ok: false,
        errors: {},
        message: res.message ?? 'Could not save profile',
      };
    }
    return {ok: true};
  },
};
