import React from 'react';
import { ExtendedForm } from '../src/ExtendedForm';
import { RJSFSchema, UiSchema, IChangeEvent } from '@rjsf/utils';
import { useConditionalUi, UiRule } from '../src/conditionals/v2';

/**
 * Global UI Rules Example
 * 
 * This example demonstrates the UI Logic Pillar of the Three Pillars architecture.
 * It shows how to:
 * 1. Show/hide form sections based on conditions
 * 2. Dynamically change widget types
 * 3. Modify field ordering based on user input
 * 4. Handle data clearing in the onChange handler (separation of concerns)
 */

// Type definition for our form data
type ShippingFormData = {
  name: string;
  email: string;
  requiresShipping: boolean;
  shippingAddress?: {
    street?: string;
    city?: string;
    zipCode?: string;
    country?: 'USA' | 'Canada' | 'Mexico' | 'Other';
    state?: string;
    province?: string;
    region?: string;
    internationalDetails?: string;
  };
  deliveryInstructions?: string;
  expressShipping?: boolean;
};

// Schema definition for a comprehensive shipping form
const schema: RJSFSchema = {
  type: 'object',
  required: ['name', 'email'],
  properties: {
    name: { 
      type: 'string', 
      title: 'Full Name' 
    },
    email: { 
      type: 'string', 
      format: 'email', 
      title: 'Email Address' 
    },
    requiresShipping: {
      type: 'boolean',
      title: 'Requires Physical Shipping?',
      default: false
    },
    shippingAddress: {
      type: 'object',
      title: 'Shipping Address',
      required: ['street', 'city', 'zipCode', 'country'],
      properties: {
        street: { 
          type: 'string', 
          title: 'Street Address' 
        },
        city: { 
          type: 'string', 
          title: 'City' 
        },
        zipCode: { 
          type: 'string', 
          title: 'ZIP/Postal Code' 
        },
        country: {
          type: 'string',
          title: 'Country',
          enum: ['USA', 'Canada', 'Mexico', 'Other'],
          default: 'USA'
        },
        // Different fields for different countries
        state: {
          type: 'string',
          title: 'State',
          enum: ['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA', 
                 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD',
                 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ',
                 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC',
                 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY']
        },
        province: {
          type: 'string',
          title: 'Province',
          enum: ['AB', 'BC', 'MB', 'NB', 'NL', 'NS', 'NT', 'NU', 'ON', 'PE', 'QC', 'SK', 'YT']
        },
        region: {
          type: 'string',
          title: 'State/Province/Region'
        },
        internationalDetails: {
          type: 'string',
          title: 'International Shipping Details',
          description: 'Please provide any special international shipping requirements'
        }
      }
    },
    deliveryInstructions: {
      type: 'string',
      title: 'Delivery Instructions',
      description: 'Special instructions for the delivery person'
    },
    expressShipping: {
      type: 'boolean',
      title: 'Express Shipping (2-3 days)',
      default: false
    }
  }
};

// Base UI Schema - defines the default UI configuration
const baseUiSchema: UiSchema = {
  'ui:order': ['name', 'email', 'requiresShipping', 'shippingAddress', 'expressShipping', 'deliveryInstructions'],
  name: { 
    'ui:autofocus': true,
    'ui:placeholder': 'Enter your full name'
  },
  email: { 
    'ui:placeholder': 'email@example.com',
    'ui:help': 'We\'ll use this for order confirmation'
  },
  shippingAddress: {
    // Initially hidden until shipping is required
    'ui:widget': 'hidden',
    'ui:order': ['street', 'city', 'country', 'state', 'province', 'region', 'zipCode'],
    street: { 
      'ui:placeholder': '123 Main St' 
    },
    city: {
      'ui:placeholder': 'New York'
    },
    zipCode: {
      'ui:placeholder': '10001'
    },
    state: {
      'ui:widget': 'select',
      'ui:placeholder': 'Select a state'
    },
    province: {
      'ui:placeholder': 'Select a province',
      // Initially hidden
      'ui:widget': 'hidden'
    },
    region: {
      'ui:placeholder': 'Enter state/province/region',
      // Initially hidden
      'ui:widget': 'hidden'
    },
    internationalDetails: {
      'ui:widget': 'hidden',  // Hidden by default
      'ui:options': { 
        rows: 3 
      }
    }
  },
  deliveryInstructions: {
    'ui:widget': 'hidden',
    'ui:options': { 
      rows: 3 
    }
  },
  expressShipping: {
    'ui:widget': 'hidden'
  }
};

// Global UI Rules using JSON Patch operations
const globalUiRules: UiRule[] = [
  // Rule 1: Show shipping address when shipping is required
  {
    name: 'Show shipping address when shipping required',
    condition: (formData) => formData.requiresShipping === true,
    effect: [
      { op: 'remove', path: '/shippingAddress/ui:widget' }
    ],
    order: 1
  },
  
  // Rule 2: Show delivery instructions when shipping is required
  {
    name: 'Show delivery instructions when shipping required',
    condition: (formData) => formData.requiresShipping === true,
    effect: [
      { op: 'replace', path: '/deliveryInstructions/ui:widget', value: 'textarea' }
    ],
    order: 2
  },
  
  // Rule 3: Show express shipping option when shipping is required
  {
    name: 'Show express shipping option when shipping required',
    condition: (formData) => formData.requiresShipping === true,
    effect: [
      { op: 'remove', path: '/expressShipping/ui:widget' }
    ],
    order: 3
  },
  
  // Rule 4: Show state dropdown only for USA
  {
    name: 'Show state field for USA',
    condition: (formData) => 
      formData.requiresShipping === true && 
      formData.shippingAddress?.country === 'USA',
    effect: [
      { op: 'remove', path: '/shippingAddress/state/ui:widget' },
      { op: 'add', path: '/shippingAddress/province/ui:widget', value: 'hidden' },
      { op: 'add', path: '/shippingAddress/region/ui:widget', value: 'hidden' }
    ],
    order: 4
  },
  
  // Rule 5: Show province dropdown only for Canada
  {
    name: 'Show province field for Canada',
    condition: (formData) => 
      formData.requiresShipping === true && 
      formData.shippingAddress?.country === 'Canada',
    effect: [
      { op: 'add', path: '/shippingAddress/state/ui:widget', value: 'hidden' },
      { op: 'remove', path: '/shippingAddress/province/ui:widget' },
      { op: 'add', path: '/shippingAddress/region/ui:widget', value: 'hidden' }
    ],
    order: 5
  },
  
  // Rule 6: Show region text field for Mexico and Other
  {
    name: 'Show region field for Mexico and Other countries',
    condition: (formData) => 
      formData.requiresShipping === true && 
      ['Mexico', 'Other'].includes(formData.shippingAddress?.country),
    effect: [
      { op: 'add', path: '/shippingAddress/state/ui:widget', value: 'hidden' },
      { op: 'add', path: '/shippingAddress/province/ui:widget', value: 'hidden' },
      { op: 'remove', path: '/shippingAddress/region/ui:widget' }
    ],
    order: 6
  },
  
  // Rule 7: Show international details only for "Other" countries
  {
    name: 'Show international details for non-North American countries',
    condition: (formData) => 
      formData.requiresShipping === true && 
      formData.shippingAddress?.country === 'Other',
    effect: [
      { op: 'replace', path: '/shippingAddress/internationalDetails/ui:widget', value: 'textarea' }
    ],
    order: 7
  },
  
  // Rule 8: Reorder fields to put international details at end when visible
  {
    name: 'Reorder fields for international shipping',
    condition: (formData) => 
      formData.requiresShipping === true && 
      formData.shippingAddress?.country === 'Other',
    effect: [
      { 
        op: 'replace', 
        path: '/shippingAddress/ui:order', 
        value: ['street', 'city', 'country', 'region', 'zipCode', 'internationalDetails'] 
      }
    ],
    order: 8
  }
];

export function GlobalUiRulesExample() {
  const [formData, setFormData] = React.useState<ShippingFormData>({
    name: '',
    email: '',
    requiresShipping: false,
    shippingAddress: {
      country: 'USA'
    }
  });
  
  // Apply UI rules to base UI schema
  // This is a pure function that only modifies the UI schema
  const conditionalUiSchema = useConditionalUi(globalUiRules, baseUiSchema, formData);
  
  // Handle form changes with data side effects
  // This demonstrates the separation of concerns between UI and data logic
  const handleChange = ({ formData: newFormData }: IChangeEvent<ShippingFormData>) => {
    let dataToSet = { ...newFormData };
    
    // DATA SIDE EFFECT: Clear shipping address when shipping is disabled
    if (formData.requiresShipping && !newFormData.requiresShipping) {
      dataToSet.shippingAddress = {
        country: 'USA' // Reset to default country
      };
      dataToSet.deliveryInstructions = '';
      dataToSet.expressShipping = false;
    }
    
    // DATA SIDE EFFECT: Clear state/province/region when country changes
    const oldCountry = formData.shippingAddress?.country;
    const newCountry = newFormData.shippingAddress?.country;
    
    if (oldCountry !== newCountry && newFormData.shippingAddress) {
      // Clear location fields when switching countries
      delete dataToSet.shippingAddress.state;
      delete dataToSet.shippingAddress.province;
      delete dataToSet.shippingAddress.region;
      delete dataToSet.shippingAddress.internationalDetails;
    }
    
    setFormData(dataToSet);
  };
  
  const handleSubmit = ({ formData }: IChangeEvent<ShippingFormData>) => {
    console.log('Form submitted:', formData);
    alert('Form submitted! Check console for details.');
  };
  
  return (
    <div style={{ padding: '20px', maxWidth: '800px', margin: '0 auto' }}>
      <h1>Global UI Rules Example</h1>
      <p>
        This example demonstrates the UI Logic Pillar of the Three Pillars conditional system.
        Try toggling "Requires Physical Shipping" and changing countries to see dynamic UI updates.
      </p>
      
      <div style={{ marginBottom: '20px', padding: '10px', backgroundColor: '#f0f0f0', borderRadius: '4px' }}>
        <h3>Features Demonstrated:</h3>
        <ul>
          <li>Show/hide form sections based on shipping requirement</li>
          <li>Dynamic widget changes (state dropdown vs province dropdown vs region text field)</li>
          <li>Conditional field ordering (international details appears at end)</li>
          <li>Data clearing when sections are hidden (handled in onChange)</li>
        </ul>
      </div>
      
      <ExtendedForm
        schema={schema}
        uiSchema={conditionalUiSchema}
        formData={formData}
        onChange={handleChange}
        onSubmit={handleSubmit}
      />
      
      <div style={{ marginTop: '20px', padding: '10px', backgroundColor: '#f9f9f9', borderRadius: '4px' }}>
        <h4>Current Form Data:</h4>
        <pre>{JSON.stringify(formData, null, 2)}</pre>
      </div>
    </div>
  );
}