// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

import { ObjectSchema, Field } from '@objectstack/spec/data';
import { cel, P } from '@objectstack/spec';

export const Opportunity = ObjectSchema.create({
  name: 'crm_opportunity',
  label: 'Opportunity',
  pluralLabel: 'Opportunities',
  icon: 'trending-up',
  description: 'A potential sale tied to an account.',

  fields: {
    name: Field.text({
      label: 'Opportunity Name',
      required: true,
      searchable: true,
      maxLength: 200,
    }),
    account: Field.lookup('crm_account', {
      label: 'Account',
      required: true,
    }),
    stage: Field.select({
      label: 'Stage',
      required: true,
      options: [
        { label: 'Prospecting', value: 'prospecting', default: true, color: '#94A3B8' },
        { label: 'Qualification', value: 'qualification', color: '#3B82F6' },
        { label: 'Proposal', value: 'proposal', color: '#F59E0B' },
        { label: 'Closed Won', value: 'closed_won', color: '#10B981' },
        { label: 'Closed Lost', value: 'closed_lost', color: '#EF4444' },
      ],
    }),
    amount: Field.currency({
      label: 'Amount',
      scale: 2,
      min: 0,
    }),
    probability: Field.percent({
      label: 'Probability',
      defaultValue: 50,
      min: 0,
      max: 100,
    }),
    expected_revenue: Field.formula({
      label: 'Expected Revenue',
      expression: cel`(amount == null ? 0 : amount) * (probability == null ? 0 : probability) / 100`,
    }),
    close_date: Field.date({
      label: 'Close Date',
    }),
    discount_percent: Field.percent({
      label: 'Discount %',
      defaultValue: 0,
      min: 0,
      max: 100,
    }),
    // Mirror target for the Discount Approval flow's approval nodes
    // (ADR-0019). The approval runtime writes the request status here; it is
    // readonly to users so only the flow drives it.
    approval_status: Field.select({
      label: 'Approval Status',
      readonly: true,
      options: [
        { label: 'Pending', value: 'pending', color: '#F59E0B' },
        { label: 'Approved', value: 'approved', color: '#10B981' },
        { label: 'Rejected', value: 'rejected', color: '#EF4444' },
        { label: 'Recalled', value: 'recalled', color: '#94A3B8' },
      ],
    }),
    renewal_of: Field.lookup('crm_opportunity', {
      label: 'Renewal Of',
    }),
  },

  validations: [
    {
      type: 'script' as const,
      name: 'discount_cap',
      label: 'Discount Cap 40%',
      description: 'Discounts over 40% require special approval.',
      condition: P`record.discount_percent != null && record.discount_percent > 40`,
      message: 'Discount cannot exceed 40% without an approved exception.',
      severity: 'error' as const,
    },
    {
      type: 'cross_field' as const,
      name: 'opp_close_date_not_past',
      label: 'Close Date Must Be Future',
      description: 'Prevent setting close_date to a date in the past on new records.',
      fields: ['close_date'],
      condition: P`has(record.close_date) && record.close_date < now()`,
      message: 'Close Date must be today or a future date.',
      events: ['insert'],
    },
    {
      type: 'state_machine' as const,
      name: 'opp_stage_transitions',
      label: 'Opportunity Stage Flow',
      description: 'Opportunities should progress through stages in order.',
      field: 'stage',
      message: 'Invalid stage transition.',
      transitions: {
        prospecting:  ['qualification', 'closed_lost'],
        qualification:['proposal', 'closed_lost'],
        proposal:     ['closed_won', 'closed_lost'],
        closed_won:   [],
        closed_lost:  ['prospecting'],
      },
    },
  ],
});
