import { adapters, migrationFields, newUuid } from '@/services/serviceConfig';
import { auditService } from '@/services/auditService';

export const DESIGN_CATEGORIES = ['Minimal','Elegant Anatomical','Gothic','Biomechanical','Cybernetic','Industrial','Skeletal','Organic','Geometric','Futuristic','Steampunk','Floral','Child Friendly','Sports Inspired','Custom'];
export const DESIGN_INTENSITY = ['Subtle','Moderate','Aggressive','Custom'];
export const SYMMETRY_OPTIONS = ['symmetric','left asymmetric','right asymmetric','mirror accents','independent medial lateral'];
export const PRIMARY_STYLES = ['smooth shell','segmented shell','ribbed shell','panelled shell','vent-accent shell','skeletal accent shell','geometric accent shell','organic flowing accent shell'];
export const ACCENT_STYLES = ['none','segmented shell','ribbed shell','panelled shell','vent-accent shell','skeletal accent shell','geometric accent shell','organic flowing accent shell'];
export const PATTERN_STYLES = ['none','smooth','segmented','flowing anatomical','gothic panel','biomechanical','geometric','ribbed','skeletal','organic vein','industrial vent','hexagonal','diamond','floral linework','star pattern','custom reference'];
export const TEXT_STYLES = ['clean modern','technical','gothic','elegant','bold','minimal'];
export const PLACEMENTS = ['front','front-lateral','outer-lateral','rear-lateral','rear','upper calf','mid calf','lower calf'];
export const LOGO_PLACEMENTS = ['front','front-lateral','outer-lateral','rear-lateral','rear'];
export const COLOURS = ['black','graphite','purple','green','red','silver','white','custom'];
export const FINISHES = ['matte','satin','gloss concept'];
export const TEXT_SIZES = ['small','medium','large'];
export const LOGO_SIZES = ['small','medium','large'];
export const CONCEPT_STATUSES = ['Draft','Workshop Review','Sent to Customer','Customer Preferred','Approved for Quote','Superseded','Rejected','Archived'];

export const PATTERN_LIBRARY = [
  { name: 'Smooth', category: 'Shell', scale: 'medium', density: 'sparse', symmetry: 'symmetric', raised: false },
  { name: 'Segmented', category: 'Shell', scale: 'medium', density: 'moderate', symmetry: 'symmetric', raised: true },
  { name: 'Flowing anatomical', category: 'Organic', scale: 'large', density: 'moderate', symmetry: 'mirror accents', raised: true },
  { name: 'Gothic panel', category: 'Architectural', scale: 'medium', density: 'dense', symmetry: 'symmetric', raised: true },
  { name: 'Biomechanical', category: 'Mechanical', scale: 'medium', density: 'dense', symmetry: 'independent medial lateral', raised: true },
  { name: 'Geometric', category: 'Abstract', scale: 'small', density: 'dense', symmetry: 'symmetric', raised: true },
  { name: 'Ribbed', category: 'Linear', scale: 'small', density: 'dense', symmetry: 'symmetric', raised: true },
  { name: 'Skeletal', category: 'Structural', scale: 'large', density: 'moderate', symmetry: 'symmetric', raised: true },
  { name: 'Organic vein', category: 'Organic', scale: 'large', density: 'moderate', symmetry: 'mirror accents', raised: false },
  { name: 'Industrial vent', category: 'Functional', scale: 'medium', density: 'moderate', symmetry: 'symmetric', raised: true },
  { name: 'Hexagonal', category: 'Geometric', scale: 'small', density: 'dense', symmetry: 'symmetric', raised: true },
  { name: 'Diamond', category: 'Geometric', scale: 'small', density: 'moderate', symmetry: 'symmetric', raised: true },
  { name: 'Floral linework', category: 'Decorative', scale: 'medium', density: 'moderate', symmetry: 'mirror accents', raised: false },
  { name: 'Star pattern', category: 'Decorative', scale: 'small', density: 'sparse', symmetry: 'symmetric', raised: true },
  { name: 'Custom reference', category: 'Custom', scale: 'medium', density: 'moderate', symmetry: 'symmetric', raised: false },
];

const COLOUR_MAP = {
  black: '#1A1A22', graphite: '#3B465A', purple: '#7E3FF2', green: '#22D37D',
  red: '#FF4D62', silver: '#C0C8D4', white: '#F5F7FB', custom: '#7E3FF2',
};

export function resolveColour(value) {
  if (!value) return null;
  if (COLOUR_MAP[value]) return COLOUR_MAP[value];
  if (/^#[0-9A-Fa-f]{6}$/.test(value)) return value;
  return COLOUR_MAP.purple;
}

export function defaultConfig(project) {
  return {
    design_category: 'Minimal',
    design_intensity: 'Subtle',
    primary_style: 'smooth shell',
    accent_style: 'none',
    accent_density: 'subtle',
    symmetry: 'symmetric',
    detail_panel_layering: false,
    detail_raised_ribs: false,
    detail_recessed_channels: false,
    detail_engraving_concept: false,
    detail_raised_ornament: false,
    main_colour: 'black',
    accent_colour: 'purple',
    logo_colour: 'silver',
    text_colour: 'silver',
    finish: 'matte',
    custom_text_enabled: false,
    custom_text: '',
    text_style: 'clean modern',
    text_placement: 'outer-lateral',
    text_orientation: 'horizontal',
    text_size: 'medium',
    text_raised: true,
    text_depth: 'shallow',
    logo_placement: 'outer-lateral',
    logo_size: 'medium',
    logo_orientation_validated: true,
    pattern_style: 'none',
    pattern_scale: 'medium',
    pattern_density: 'moderate',
    pattern_rotation_degrees: 0,
    pattern_placement_region: 'outer-lateral',
    pattern_raised: true,
    vent_concept: '',
    surface_notes: '',
    inspiration_notes: '',
    reference_image_urls: [],
    concept_status: 'Draft',
    approved_for_quote: false,
  };
}

function validateLogo(config, project, ossiguard) {
  const issues = [];
  // Logo presence — mandatory, always present after orientation fix
  if (!config.logo_placement) issues.push({ level: 'blocked', text: 'SHiRE logo placement not set — mandatory branding missing' });
  // Orientation — the branding layer enforces outward-facing + backFaceCulling, so a mirrored logo
  // can only occur if orientation_validated is explicitly false (legacy data or forced override).
  if (config.logo_orientation_validated === false) {
    issues.push({ level: 'blocked', text: 'SHiRE logo orientation is MIRRORED — must be corrected before approval' });
  }
  // Logo size acceptable
  if (!config.logo_size) issues.push({ level: 'warning', text: 'Logo size not set' });
  // Logo clear of seams — rear placement may cross a cover boundary seam
  if (project && project.cover_boundaries && config.logo_placement === 'rear') {
    issues.push({ level: 'warning', text: 'Logo on rear face — verify it does not cross a seam or cover boundary' });
  }
  // Logo clear of Ossiguard — outer-lateral logo may sit near the connector
  if (ossiguard && (config.logo_placement === 'outer-lateral' || config.logo_placement === 'front-lateral')) {
    const connectorSide = (ossiguard.medial_offset_mm || 0) >= 0 ? 'lateral' : 'medial';
    if (connectorSide === 'lateral') {
      issues.push({ level: 'warning', text: 'Logo on lateral face — verify it does not overlap the Ossiguard connector body' });
    }
  }
  // Logo clear of sensitive zones
  if (project && project.sensitive_area_summary && config.logo_placement === 'front') {
    issues.push({ level: 'warning', text: 'Logo on front face — verify it does not overlap a sensitive zone' });
  }
  return issues;
}

function validateText(config, project, ossiguard) {
  const issues = [];
  if (!config.custom_text_enabled) return issues;
  const text = (config.custom_text || '').trim();
  if (!text) issues.push({ level: 'warning', text: 'Custom text enabled but no text entered' });
  if (text.length > 40) issues.push({ level: 'blocked', text: 'Custom text too long (max 40 characters)' });
  else if (text.length > 24) issues.push({ level: 'warning', text: 'Custom text is long — visual quality may reduce' });
  if (text.length > 0 && text.length < 2) issues.push({ level: 'warning', text: 'Custom text is very short — may not be legible' });
  if (!config.text_placement) issues.push({ level: 'warning', text: 'Custom text placement not set' });
  // Text overlaps logo
  if (config.text_placement && config.logo_placement && config.text_placement === config.logo_placement) {
    issues.push({ level: 'warning', text: 'Custom text overlaps SHiRE logo placement region' });
  }
  // Text crosses Ossiguard access
  if (ossiguard && (config.text_placement === 'outer-lateral' || config.text_placement === 'front-lateral')) {
    issues.push({ level: 'warning', text: 'Verify custom text does not intersect Ossiguard access or fastener clearance' });
  }
  // Text conflicts with sensitive zone
  if (project && project.sensitive_area_summary && config.custom_text_enabled) {
    issues.push({ level: 'warning', text: 'Verify custom text does not overlap sensitive zones described in the project brief' });
  }
  // Text mirrored — symmetry mirror accents should not mirror readable text
  if (config.symmetry === 'mirror accents' && config.text_placement) {
    issues.push({ level: 'warning', text: 'Mirror-accent symmetry does not mirror readable text or logos — text remains single-sided' });
  }
  return issues;
}

function validateOssiguardConflicts(config, project, ossiguard) {
  const issues = [];
  if (!ossiguard) return issues;
  // Pattern/panel on the connector side may obstruct access
  const connectorSide = (ossiguard.medial_offset_mm || 0) >= 0 ? 'lateral' : 'medial';
  if (config.pattern_style && config.pattern_style !== 'none' && config.pattern_placement_region === 'outer-lateral' && connectorSide === 'lateral') {
    issues.push({ level: 'warning', text: 'Exterior pattern on connector side — verify it does not obstruct Ossiguard insertion/removal path' });
  }
  if (config.detail_access_door_styling && connectorSide === 'lateral') {
    issues.push({ level: 'warning', text: 'Access-door styling near connector — verify fastener access and release path remain unobstructed' });
  }
  if (ossiguard.panel_opening_required && config.pattern_style && config.pattern_style !== 'none') {
    issues.push({ level: 'warning', text: 'Panel opening required for Ossiguard — verify pattern does not block the opening' });
  }
  return issues;
}

export const designService = {
  list: () => adapters.database.list('DesignConfiguration'),
  forProject: (project_uuid) => adapters.database.filter('DesignConfiguration', { project_uuid }, '-version'),
  getConcepts: (project_uuid) => {
    const all = adapters.database.filter('DesignConfiguration', { project_uuid }, '-version');
    return all;
  },
  getCurrent: async (project_uuid) => {
    const all = await adapters.database.filter('DesignConfiguration', { project_uuid, is_current: true }, '-version', 1);
    return all[0] || null;
  },
  get: async (uuid) => (await adapters.database.filter('DesignConfiguration', { uuid }, '-updated_date', 1))[0],
  async create(data, actor) {
    const existing = await adapters.database.filter('DesignConfiguration', { project_uuid: data.project_uuid });
    const version = (existing.length ? Math.max(...existing.map((d) => d.version || 0)) : 0) + 1;
    const record = await adapters.database.create('DesignConfiguration', {
      ...data, uuid: newUuid('design'), version, is_current: true,
      validation_status: data.validation_status || 'Warning',
      validation_issues: data.validation_issues || [],
      ...migrationFields(actor),
    });
    for (const d of existing) {
      if (d.id !== record.id && d.is_current) {
        await adapters.database.update('DesignConfiguration', d.id, { is_current: false, updated_by_name: actor });
      }
    }
    await auditService.record('design_created', 'DesignConfiguration', record.uuid, `Design revision v${version} created`, actor);
    return record;
  },
  async update(id, uuid, data, actor) {
    const { id: _id, created_date, updated_date, created_by_id, ...editable } = data;
    const validated = designService.validate({ ...editable });
    const record = await adapters.database.update('DesignConfiguration', id, { ...editable, validation_status: validated.status, validation_issues: validated.issues, updated_by_name: actor });
    await auditService.record('design_updated', 'DesignConfiguration', uuid, 'Design configuration updated', actor);
    return record;
  },
  async saveRevision(project_uuid, data, actor) {
    const existing = await adapters.database.filter('DesignConfiguration', { project_uuid });
    const version = (existing.length ? Math.max(...existing.map((d) => d.version || 0)) : 0) + 1;
    const validated = designService.validate(data);
    const record = await adapters.database.create('DesignConfiguration', {
      ...data, uuid: newUuid('design'), project_uuid, version, is_current: true,
      validation_status: validated.status, validation_issues: validated.issues,
      ...migrationFields(actor),
    });
    for (const d of existing) {
      if (d.id !== record.id && d.is_current) {
        await adapters.database.update('DesignConfiguration', d.id, { is_current: false, updated_by_name: actor });
      }
    }
    await auditService.record('design_revision_saved', 'DesignConfiguration', record.uuid, `Design revision v${version} saved`, actor);
    return record;
  },
  async duplicate(project_uuid, actor) {
    const current = await designService.getCurrent(project_uuid);
    if (!current) return null;
    const { id, uuid, created_date, updated_date, created_by_id, version, is_current, ...rest } = current;
    return designService.saveRevision(project_uuid, rest, actor);
  },
  async restore(designUuid, actor) {
    const rev = await designService.get(designUuid);
    if (!rev) return null;
    const all = await adapters.database.filter('DesignConfiguration', { project_uuid: rev.project_uuid });
    for (const d of all) {
      await adapters.database.update('DesignConfiguration', d.id, { is_current: d.uuid === designUuid, updated_by_name: actor });
    }
    await auditService.record('design_restored', 'DesignConfiguration', designUuid, `Design revision v${rev.version} restored as current`, actor);
    return designService.get(designUuid);
  },
  async approveForQuote(uuid, actor) {
    const rev = await designService.get(uuid);
    if (!rev) return null;
    const v = designService.validate(rev);
    if (v.status === 'Blocked') {
      return { error: 'Cannot approve — blocking validation failures remain', validation: v };
    }
    const record = await adapters.database.update('DesignConfiguration', rev.id, { approved_for_quote: true, concept_status: 'Approved for Quote', approved_design_uuid: uuid, updated_by_name: actor });
    await auditService.record('design_approved', 'DesignConfiguration', uuid, 'Design approved for quote (not CAD/print ready)', actor);
    return record;
  },
  async copyToProject(sourceProjectUuid, targetProjectUuid, actor) {
    const current = await designService.getCurrent(sourceProjectUuid);
    if (!current) return null;
    const { id, uuid, created_date, updated_date, created_by_id, version, is_current, project_uuid, ...rest } = current;
    return designService.saveRevision(targetProjectUuid, rest, actor);
  },
  async setConceptStatus(uuid, status, actor) {
    const rev = await designService.get(uuid);
    if (!rev) return null;
    const record = await adapters.database.update('DesignConfiguration', rev.id, { concept_status: status, updated_by_name: actor });
    await auditService.record('concept_status', 'DesignConfiguration', uuid, `Concept status set to ${status}`, actor);
    return record;
  },
  async recordFeedback(uuid, feedback, actor) {
    const rev = await designService.get(uuid);
    if (!rev) return null;
    const record = await adapters.database.update('DesignConfiguration', rev.id, { customer_feedback: feedback, updated_by_name: actor });
    await auditService.record('concept_feedback', 'DesignConfiguration', uuid, 'Customer feedback recorded', actor);
    return record;
  },
  async createConcept(project_uuid, data, actor) {
    const existing = await adapters.database.filter('DesignConfiguration', { project_uuid });
    const version = (existing.length ? Math.max(...existing.map((d) => d.version || 0)) : 0) + 1;
    const record = await adapters.database.create('DesignConfiguration', {
      ...data, uuid: newUuid('design'), project_uuid, version, is_current: false,
      concept_status: data.concept_status || 'Draft',
      validation_status: 'Warning', validation_issues: [],
      ...migrationFields(actor),
    });
    await auditService.record('concept_created', 'DesignConfiguration', record.uuid, `Concept "${data.concept_name || 'Untitled'}" created`, actor);
    return record;
  },
  validate(config, project, ossiguard) {
    const issues = [];
    if (!config) return { status: 'Blocked', issues: ['No design configuration saved'] };
    // Core field checks
    if (!config.main_colour) issues.push({ level: 'warning', text: 'Main cover colour not set' });
    if (!config.accent_colour) issues.push({ level: 'warning', text: 'Accent colour not set' });
    // Logo validation
    issues.push(...validateLogo(config, project, ossiguard));
    // Text validation
    issues.push(...validateText(config, project, ossiguard));
    // Ossiguard conflict validation
    issues.push(...validateOssiguardConflicts(config, project, ossiguard));
    const hasBlocked = issues.some((i) => i.level === 'blocked');
    const hasWarning = issues.some((i) => i.level === 'warning');
    const status = hasBlocked ? 'Blocked' : hasWarning ? 'Warning' : 'Pass';
    return { status, issues: issues.map((i) => i.text), issueObjects: issues };
  },
  logoValidation(config, project, ossiguard) {
    const checks = validateLogo(config, project, ossiguard);
    const mirrored = checks.some((c) => c.text.toLowerCase().includes('mirrored'));
    return {
      present: !!config.logo_placement,
      readable: !!config.logo_size,
      orientationCorrect: config.logo_orientation_validated !== false,
      notMirrored: !mirrored,
      exteriorFacing: true,
      sizeAcceptable: !!config.logo_size,
      issues: checks,
      level: checks.some((c) => c.level === 'blocked') ? 'blocked' : checks.some((c) => c.level === 'warning') ? 'warning' : 'pass',
    };
  },
  status: () => ({ implemented: true, label: 'Design Forge active', boundary: 'Design elements are conceptual preview only — not manufacturing-ready CAD geometry.' }),
};