// listings.jsx — Real CEG listing-agreement schemas + draft templates
// Source: CEG boilerplate Word docs (Lease, Sale, Sale or Lease).
// Mutates the schema/template/demo registries owned by data.jsx.

const { Filled } = window;

// ─── Field-builder shorthand (local) ────────────────────────────────────
const T   = (id, label, o={}) => ({ id, label, type: 'text', ...o });
const TA  = (id, label, o={}) => ({ id, label, type: 'textarea', ...o });
const SFn = (id, label, o={}) => ({ id, label, type: 'sf', ...o });
const PCT = (id, label, o={}) => ({ id, label, type: 'percent', ...o });
const USD = (id, label, o={}) => ({ id, label, type: 'currency', suffix: 'USD', ...o });
const PSF = (id, label, o={}) => ({ id, label, type: 'currency', suffix: 'PSF/yr', ...o });
const PSFflat = (id, label, o={}) => ({ id, label, type: 'currency', suffix: 'PSF', ...o });
const DT  = (id, label, o={}) => ({ id, label, type: 'date', ...o });
const SEL = (id, label, options, o={}) => ({ id, label, type: 'select', options, ...o });
const EML = (id, label, o={}) => ({ id, label, type: 'email', ...o });
const TEL = (id, label, o={}) => ({ id, label, type: 'tel', ...o });

// CEG broker directory — single source of truth. Any form's broker dropdown
// reads BROKERS from the keys, and the cascade auto-fills brokerEmail when
// a name is selected. To add/remove a broker or fix an email, edit ONLY
// this object — the dropdown options and the cascade both update.
const BROKER_DIRECTORY = {
  'Brady Erickson':   'brady@cegspaces.com',
  'Brian Lee':        'brianlee@cegspaces.com',
  'Brian Potratz':    'brian@cegspaces.com',
  'Curran Poganski':  'curran@cegspaces.com',
  'Diane Signorelli': 'diane@cegspaces.com',
  'Halie Aarestad':   'halie@cegspaces.com',
  'Jack Potratz':     'jack.potratz@cegspaces.com',
  'Jeff Salzbrun':    'jeff@cegspaces.com',
  'Joseph Nickleson': 'joseph@cegspaces.com',
  'Max Giblin':       'max.giblin@cegspaces.com',
  'Mike Ruhland':     'mike@cegspaces.com',
  'Nicole Langer':    'nicole@cegspaces.com',
  'Shannon Farrand':  'shannon@cegspaces.com',
};
const BROKERS = Object.keys(BROKER_DIRECTORY);
// Cascade map for the broker SEL field: { 'Brady Erickson': { brokerEmail: 'brady@...' }, ... }
const BROKER_EMAIL_CASCADE = Object.fromEntries(
  Object.entries(BROKER_DIRECTORY).map(([name, email]) => [name, { brokerEmail: email }])
);
// Expose the directory + cascade as window globals so reps.jsx (and any
// future doc-type module) can reuse them without redefinition. Single
// source of truth lives here in listings.jsx.
window.__BROKER_DIRECTORY__ = BROKER_DIRECTORY;
window.__BROKERS__ = BROKERS;
window.__BROKER_EMAIL_CASCADE__ = BROKER_EMAIL_CASCADE;
const SPACE_TYPES = ['Office','Industrial','Industrial Flex','Retail','Restaurant / Bar','Mixed Use','Warehouse','Land','Government / Public','Other'];

const OPT1 = 'Option 1 — Office (flat per SF)';
const OPT2 = 'Option 2 — Industrial (graduated % of net rent)';
const LEASE_STRUCTURES = [OPT1, OPT2];

// ─── Reusable section builders ─────────────────────────────────────────
const propertySection = (includeSF = true) => ({
  id: 'property', title: 'Property', icon: 'building-2',
  fields: [
    T('propertyAddress', 'Property address', { required: true, span: 2, placeholder: '2400 Wacker Dr' }),
    T('propertyCity', 'City', { required: true, span: 1, placeholder: 'Minneapolis' }),
    T('propertyZip', 'ZIP', { required: true, span: 1, placeholder: '55401', help: 'State is Minnesota (locked by boilerplate).' }),
    ...(includeSF ? [
      SFn('approxSF', 'Approximate SF', { required: true, span: 1, placeholder: '14,200' }),
      SEL('spaceType', 'Space type', SPACE_TYPES, { required: true, span: 1 }),
    ] : []),
  ],
});

const ownerSection = (label, sub) => ({
  id: 'owner', title: label, icon: 'briefcase',
  fields: [
    T('ownerEntity', `${sub} entity`, { required: true, span: 2, placeholder: 'Wacker Riverfront LLC', help: 'Legal entity as titled on the deed.' }),
    T('signatoryName', 'Signatory name', { required: true, span: 1, placeholder: 'Mark Allen' }),
    T('signatoryTitle', 'Signatory title', { span: 1, placeholder: 'Managing Member' }),
    EML('ownerEmail', 'Email', { required: true, span: 1, placeholder: 'mark@wackerriver.com' }),
    TEL('ownerPhone', 'Phone', { span: 1, placeholder: '(612) 555-0188' }),
  ],
});

const periodSection = () => ({
  id: 'period', title: 'Listing Period', icon: 'calendar-days',
  fields: [
    DT('effectiveDate', 'Effective date', { required: true, span: 1 }),
    DT('expirationDate', 'Expiration date', { required: true, span: 1, locked: true, help: 'Auto-set to 1 year + 1 month after the effective date, rounded to end of month.' }),
  ],
});

const OPT1_DEFAULTS = { opt1Rate: '1.00', opt1OutsideMult: '150', opt1RenewalRate: '0.50', paySplitExec: '50', paySplitCommence: '50' };
const OPT2_DEFAULTS = { opt2Y1: '7', opt2Y2: '6', opt2Y3: '5', opt2Y4: '4', opt2Y5plus: '3', opt2CoBrokerMult: '150', paySplitExec: '50', paySplitCommence: '50' };

const leaseCommissionFields = () => ([
  SEL('leaseStructure', 'Commission structure', LEASE_STRUCTURES, {
    required: true, span: 2,
    help: 'Office → Option 1. Industrial → Option 2. Details auto-fill from CEG boilerplate and lock once chosen — changes require Jeff.',
    cascade: { [OPT1]: OPT1_DEFAULTS, [OPT2]: OPT2_DEFAULTS },
  }),
  // Option 1 fields
  PSF('opt1Rate', 'Rate · per SF / year', { span: 1, default: '1.00', locked: true, showIf: { leaseStructure: OPT1 } }),
  PCT('opt1OutsideMult', 'Outside-broker multiplier', { span: 1, default: '150', locked: true, showIf: { leaseStructure: OPT1 } }),
  PSF('opt1RenewalRate', 'Renewal rate · per SF / year', { span: 2, default: '0.50', locked: true, help: 'Paid only if Landlord requests Broker negotiate a renewal in writing.', showIf: { leaseStructure: OPT1 } }),
  // Option 2 fields (graduated)
  PCT('opt2Y1', 'Year 1 %', { span: 1, default: '7', locked: true, showIf: { leaseStructure: OPT2 } }),
  PCT('opt2Y2', 'Year 2 %', { span: 1, default: '6', locked: true, showIf: { leaseStructure: OPT2 } }),
  PCT('opt2Y3', 'Year 3 %', { span: 1, default: '5', locked: true, showIf: { leaseStructure: OPT2 } }),
  PCT('opt2Y4', 'Year 4 %', { span: 1, default: '4', locked: true, showIf: { leaseStructure: OPT2 } }),
  PCT('opt2Y5plus', 'Year 5+ %', { span: 1, default: '3', locked: true, help: 'Year 5 and each year after.', showIf: { leaseStructure: OPT2 } }),
  PCT('opt2CoBrokerMult', 'Co-broker multiplier', { span: 1, default: '150', locked: true, showIf: { leaseStructure: OPT2 } }),
  // Payment split (visible once structure is chosen)
  PCT('paySplitExec', 'Payment % on lease execution', { span: 1, default: '50', locked: true, showIf: { leaseStructure: [OPT1, OPT2] } }),
  PCT('paySplitCommence', 'Payment % on lease commencement', { span: 1, default: '50', locked: true, showIf: { leaseStructure: [OPT1, OPT2] } }),
]);

const saleCommissionFields = () => ([
  PCT('saleAgentPct', 'Agent commission %', { span: 1, default: '5', locked: true, help: 'CEG default 5%. Changes require Jeff — lower price may warrant a higher fee.' }),
  PCT('saleCoBrokerPct', 'Additional Co-Broker %', { span: 1, default: '1', locked: true, help: 'CEG default 1% additional.' }),
]);

const agentSection = () => ({
  id: 'agent', title: 'CEG Agent', icon: 'user-round',
  fields: [
    SEL('broker', 'Listing broker', BROKERS, {
      required: true, span: 1,
      help: 'Email auto-fills from the CEG directory.',
      cascade: BROKER_EMAIL_CASCADE,
    }),
    EML('brokerEmail', 'Broker email', { required: true, span: 1, placeholder: 'broker@cegspaces.com', help: 'Auto-filled when you pick a broker — edit only if it should differ.' }),
  ],
});

const exhibitSection = () => ({
  id: 'exhibit', title: 'Exhibit A — Legal Description', icon: 'file-text',
  fields: [
    TA('legalDescription', 'Legal description', { span: 2, placeholder: 'Lot 4, Block 2, Wacker Riverfront Addition…', help: 'Paste from title commitment or abstract.' }),
    T('parcelId', 'Parcel ID (PID)', { span: 1, placeholder: '17-029-24-44-0089' }),
    { id: 'propertyImage', label: 'Property image', type: 'image', span: 2, help: 'Optional — if skipped, you must add the photo to the Word version before sending.' },
  ],
});

// ════════════════════════════════════════════════════════════════════════
// SCHEMAS
// ════════════════════════════════════════════════════════════════════════

const SCHEMA_LEASE = {
  title: 'Lease Listing Agreement',
  subtitle: 'Owner-side listing — lease only (CEG Lease boilerplate)',
  sections: [
    propertySection(true),
    ownerSection('Owner (Lessor)', 'Lessor'),
    periodSection(),
    {
      id: 'commission', title: 'Lease Commission', icon: 'percent',
      fields: leaseCommissionFields(),
    },
    agentSection(),
    exhibitSection(),
  ],
};

const SCHEMA_SALE = {
  title: 'Sale Listing Agreement',
  subtitle: 'Owner-side listing — sale only (CEG Sale boilerplate)',
  sections: [
    propertySection(false),
    ownerSection('Owner (Seller)', 'Seller'),
    periodSection(),
    {
      id: 'price', title: 'Sale Price', icon: 'tag',
      fields: [
        USD('priceNumeric', 'Listing price (numeric)', { required: true, span: 1, placeholder: '2,450,000' }),
        T('priceWords', 'Listing price (written out)', { required: true, span: 1, placeholder: 'Two Million Four Hundred Fifty Thousand', help: 'Required in legal document — must spell out the amount.' }),
      ],
    },
    {
      id: 'commission', title: 'Sale Commission', icon: 'percent',
      fields: saleCommissionFields(),
    },
    agentSection(),
    exhibitSection(),
  ],
};

const SCHEMA_LEASE_SALE = {
  title: 'Lease or Sale Listing Agreement',
  subtitle: 'Combined owner-side mandate — both lease and sale (CEG Sale-or-Lease boilerplate)',
  sections: [
    propertySection(true),
    ownerSection('Owner', 'Owner'),
    periodSection(),
    {
      id: 'price', title: 'Sale Price', icon: 'tag',
      fields: [
        USD('priceNumeric', 'Listing price (numeric)', { required: true, span: 1, placeholder: '2,450,000' }),
        T('priceWords', 'Listing price (written out)', { required: true, span: 1, placeholder: 'Two Million Four Hundred Fifty Thousand' }),
      ],
    },
    {
      id: 'leaseRate', title: 'Asking Lease Rate', icon: 'square-stack',
      fields: [
        PSF('askingLeaseRate', 'Asking lease rate', { required: true, span: 2, placeholder: '12.50', help: 'Per square foot per year.' }),
      ],
    },
    {
      id: 'saleCommission', title: 'Sale Commission', icon: 'percent',
      fields: saleCommissionFields(),
    },
    {
      id: 'leaseCommission', title: 'Lease Commission', icon: 'percent',
      fields: leaseCommissionFields(),
    },
    agentSection(),
    exhibitSection(),
  ],
};

// ════════════════════════════════════════════════════════════════════════
// DRAFT TEMPLATES — full faithful legal language from CEG boilerplates
// ════════════════════════════════════════════════════════════════════════

// Helpers
const F = (v, ph) => <Filled>{v || ph}</Filled>;
const addr = (v) => [v.propertyAddress, v.propertyCity].filter(Boolean).join(', ') || '[Property Address, City]';
const fullAddr = (v) => {
  const parts = [v.propertyAddress, v.propertyCity, v.propertyZip].filter(Boolean);
  return parts.length ? parts.join(', ') + (parts.length < 3 ? ', Minnesota' : ', Minnesota').replace(/Minnesota/, '') + ', Minnesota ' + (v.propertyZip || '[ZIP]') : '[Property Address, City], Minnesota [ZIP]';
};

const fmtAddr = (v) => (
  <>{F(v.propertyAddress, '[PROPERTY ADDRESS]')}, {F(v.propertyCity, '[CITY]')}, Minnesota {F(v.propertyZip, '[ZIP]')}</>
);

const fmtDate = (v) => F(v.effectiveDate ? formatLongDate(v.effectiveDate) : null, '[MONTH DAY, YEAR]');
const fmtExpDate = (v) => F(v.expirationDate ? formatLongDate(v.expirationDate) : null, '[MONTH DAY, YEAR]');

function formatLongDate(iso) {
  if (!iso) return null;
  const d = new Date(iso + 'T00:00:00');
  if (isNaN(d.getTime())) return iso;
  return d.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
}

// ─── Shared section: NOTICE ─────────────────────────────────────────────
const noticeSection = () => ({
  id: 'notice', title: 'Notice', legalRef: '§ 2',
  body: (
    <p style={{textTransform:'uppercase', letterSpacing:'0.04em', fontSize:'13px', fontWeight:600, color:'var(--ink-700)'}}>
      Notice: The compensation for the sale, lease, rental, or management of real property shall be determined between each individual broker and the broker's client.
    </p>
  ),
});

// ─── Shared section: General Provisions ─────────────────────────────────
const generalProvisions = (label, count) => ({
  id: 'general', title: 'General Provisions', legalRef: `§ ${count}`,
  body: (
    <>
      <p>
        It is acknowledged that the Brokerage Fee is and shall be deemed to be a share of the {label === 'lease' ? 'rent and other consideration' : (label === 'sale' ? 'purchase money' : 'purchase money or rent and other consideration')} received by {label === 'lease' ? 'LESSOR' : (label === 'sale' ? 'SELLER' : 'OWNER')}{label === 'both' ? ', as applicable,' : ''} {label === 'lease' ? 'under any lease procured pursuant to this Agreement, ' : ''}and BROKER shall be secured by, and shall have a security interest in, such funds until the Brokerage Fee is paid in full.
      </p>
      <p>
        {label === 'lease' ? 'LESSOR' : (label === 'sale' ? 'SELLER' : 'OWNER')} hereby permits BROKER to share part of its commission with other real estate brokers, including brokers representing only the {label === 'lease' ? 'tenant' : (label === 'sale' ? 'purchaser' : 'purchaser or tenant')}. {label === 'lease' ? 'LESSOR' : (label === 'sale' ? 'SELLER' : 'OWNER')} authorizes BROKER to allow subagents or agents representing a {label === 'lease' ? 'tenant' : (label === 'sale' ? 'purchaser' : 'purchaser or tenant')} to market the Property and to share the Brokerage Fee with {label === 'both' ? 'such broker' : 'a ' + (label === 'lease' ? 'tenant' : 'purchaser') + "'s broker"}. {label === 'lease' ? 'LESSOR' : (label === 'sale' ? 'SELLER' : 'OWNER')} agrees that BROKER may list other properties during the term of this Agreement which may compete with {label === 'lease' ? 'LESSOR' : (label === 'sale' ? 'SELLER' : 'OWNER')}'s Property.
      </p>
      <p>
        {label === 'lease' ? 'LESSOR' : (label === 'sale' ? 'SELLER' : 'OWNER')} and BROKER agree that this Listing Agreement may be signed in counterparts, including by electronic or email signatures, each of which shall be deemed an original and all of which together shall constitute one and the same instrument.
      </p>
      <p>
        This Agreement is binding upon the heirs, successors, and assigns of the parties. This Agreement constitutes the complete agreement between the parties and supersedes any prior oral or written agreements between the parties relative to the provisions herein. If either BROKER or {label === 'lease' ? 'LESSOR' : (label === 'sale' ? 'SELLER' : 'OWNER')} brings an action to enforce this Agreement, the prevailing party shall be entitled to recover all costs and expenses, including all reasonable attorneys' fees and costs. No amendment, modification, or extension of this Agreement shall be valid or binding unless made in writing and signed by both {label === 'lease' ? 'LESSOR' : (label === 'sale' ? 'SELLER' : 'OWNER')} and BROKER. This contract shall be governed by the laws of the State of Minnesota.
      </p>
    </>
  ),
});

// ─── Shared section: Signatures ────────────────────────────────────────
const signaturesSection = (role, ownerLabel, count) => ({
  id: 'signatures', title: 'Signatures', legalRef: `§ ${count}`,
  body: (
    <>
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:'40px 32px', marginTop:'8px'}}>
        <div>
          <p style={{marginBottom:6}}><strong>{F(role, '[OWNER NAME]')}</strong></p>
          <p style={{margin:'4px 0', color:'var(--ink-700)', fontSize:'12px', letterSpacing:'0.06em', textTransform:'uppercase'}}>{ownerLabel}</p>
          <p style={{marginTop:24}}>By: ____________________________________</p>
          <p>Its: ___________________________________</p>
          <p>Date: _________________________________</p>
        </div>
        <div>
          <p style={{marginBottom:6}}><strong>COMMERCIAL EQUITIES GROUP, INC.</strong></p>
          <p style={{margin:'4px 0', color:'var(--ink-700)', fontSize:'12px', letterSpacing:'0.06em', textTransform:'uppercase'}}>Broker</p>
          <p style={{marginTop:24}}>By: ____________________________________</p>
          <p>Its: ___________________________________</p>
          <p>Date: _________________________________</p>
        </div>
      </div>
    </>
  ),
});

// ─── Shared section: Agent block ───────────────────────────────────────
const agentBlock = (v, count) => ({
  id: 'agent', title: 'Agent(s)', legalRef: `§ ${count}`,
  body: (
    <>
      <p style={{marginBottom:8}}><strong>Agent(s):</strong></p>
      <p style={{margin:'4px 0'}}>{F(v.broker, '[AGENT NAME]')}</p>
      <p style={{margin:'4px 0'}}>{F(v.brokerEmail, '[AGENT EMAIL]')}</p>
    </>
  ),
});

// ─── Shared section: Exhibit A ─────────────────────────────────────────
const exhibitBlock = (v, ownerEntity, count) => ({
  id: 'exhibit', title: 'Exhibit A — Legal Description of Property', legalRef: `§ ${count}`,
  body: (
    <>
      <p style={{textAlign:'center', fontStyle:'italic', color:'var(--ink-600)', marginBottom:18}}>
        By and Between<br/>
        {F(ownerEntity, '[OWNER NAME]')}<br/>
        and<br/>
        Commercial Equities Group, Inc.
      </p>
      <p style={{textAlign:'center', textTransform:'uppercase', letterSpacing:'0.06em', fontSize:13, fontWeight:600, color:'var(--ink-700)'}}>Legal Description of Property</p>
      <p style={{marginTop:18}}>{fmtAddr(v)}</p>
      <p style={{whiteSpace:'pre-wrap'}}>{F(v.legalDescription, '[LEGAL DESCRIPTION]')}</p>
      <p style={{marginTop:14}}>Parcel ID: {F(v.parcelId, '[PARCEL ID]')}</p>
      {v.propertyImage ? (
        <img src={v.propertyImage} alt="Property" style={{display:'block', maxWidth:'100%', maxHeight:280, margin:'18px auto 0', borderRadius:8, boxShadow:'var(--shadow-sm)'}} />
      ) : (
        <p style={{marginTop:18, padding:'18px 22px', border:'1px dashed var(--border-strong)', borderRadius:8, background:'var(--ink-50)', textAlign:'center', color:'var(--ink-500)', fontStyle:'italic'}}>[Property Image — add to Word version before sending]</p>
      )}
    </>
  ),
});

// ─── Commission body builders ──────────────────────────────────────────
const renderLeaseCommissionBody = (v, partyLabel) => {
  const partyCaps = partyLabel.toUpperCase();
  return (
    <>
      <p>{partyCaps} shall pay BROKER a Brokerage Fee under any of the following conditions:</p>
      <ol style={{paddingLeft:24, margin:'8px 0 16px'}}>
        <li style={{marginBottom:8}}>The lease of the Property during the period of this Agreement by BROKER or any other broker not a party to this Agreement; or</li>
        <li style={{marginBottom:8}}>{partyCaps} contributes or conveys the Property, or any interest therein, to a partnership, joint venture, or other business entity during the term of this Agreement in lieu of a lease of the Property; or</li>
        <li style={{marginBottom:8}}>{partyCaps} is a partnership or other business entity and an interest in the partnership or other business entity is transferred, whether by merger, outright purchase, or otherwise, in lieu of a lease of the Property during the term of this Agreement; or</li>
        <li>The lease of the Property within one hundred eighty (180) days after the expiration or termination of this Agreement to any prospect with whom BROKER has negotiated or to whom BROKER has exhibited the Property during the period of this Agreement, or whose name was disclosed to {partyCaps} in writing by BROKER not later than seventy-two (72) hours after the expiration or termination of this Agreement.</li>
      </ol>
      <p>The above timeframes shall be extended provided there are ongoing negotiations between {partyCaps} and a prospective tenant beyond the expiration date.</p>

      {v.leaseStructure === OPT1 && (
        <p style={{marginTop:14}}>
          <strong>Option 1 — Flat Per Square Foot (typical for Office).</strong> Leases of twelve (12) months or less shall be one (1) month's gross rent. Leases beyond twelve (12) months shall be {F(v.opt1Rate ? '$' + v.opt1Rate : null, '[$1.00]')} per square foot per year. If an outside broker brings a tenant to the Property and a lease is entered into, the commission for the lease shall be {F(v.opt1OutsideMult ? v.opt1OutsideMult + '%' : null, '[150%]')} of the above schedule. It is expected that Landlord will negotiate renewal leases with Tenant, but Landlord, may at its sole discretion, request, in writing, for Broker to negotiate a lease renewal with an existing Tenant. Upon full execution of lease renewal Broker will be paid {F(v.opt1RenewalRate ? '$' + v.opt1RenewalRate : null, '[$0.50]')} per square foot per year plus any fees charged by an outside broker as agreed to in advance by Landlord.
        </p>
      )}

      {v.leaseStructure === OPT2 && (
        <p style={{marginTop:14}}>
          <strong>Option 2 — Graduated Percentage of Net Rent (typical for Industrial).</strong> {partyCaps} shall pay BROKER a Brokerage Fee of {F(v.opt2Y1 ? v.opt2Y1 + '%' : null, '[7%]')} of Year One Net Rent, {F(v.opt2Y2 ? v.opt2Y2 + '%' : null, '[6%]')} of Year Two Net Rent, {F(v.opt2Y3 ? v.opt2Y3 + '%' : null, '[5%]')} of Year Three Net Rent, {F(v.opt2Y4 ? v.opt2Y4 + '%' : null, '[4%]')} of Year Four Net Rent, {F(v.opt2Y5plus ? v.opt2Y5plus + '%' : null, '[3%]')} of Year Five Net Rent, and {F(v.opt2Y5plus ? v.opt2Y5plus + '%' : null, '[3%]')} of Net Rent for each year thereafter for the initial lease term, for a direct deal with the agent(s) listed below. In the event a Co-Broker, other than the agent(s) listed below, is engaged, {partyCaps} shall pay BROKER {F(v.opt2CoBrokerMult ? v.opt2CoBrokerMult + '%' : null, '[150%]')} of the above commission schedule.
        </p>
      )}

      {!v.leaseStructure && (
        <p style={{marginTop:14, padding:'12px 14px', background:'var(--warning-bg)', borderRadius:8, color:'#6b4900', fontSize:13}}>
          ⚠ Commission structure not yet selected. Pick Option 1 (Office) or Option 2 (Industrial) in the form to populate this clause.
        </p>
      )}

      <p style={{marginTop:14}}>
        <strong>Payment Terms (applies to either option above).</strong> The leasing commission shall be paid in the following manner: {F(v.paySplitExec ? v.paySplitExec + '%' : null, '[50%]')} upon full execution of a lease and {F(v.paySplitCommence ? v.paySplitCommence + '%' : null, '[50%]')} upon lease commencement. If an outside broker requests a higher fee as part of any leasing proposal, notice shall be given to {partyCaps} of the request, and {partyCaps} may accept or reject payment of the higher fee at {partyCaps}'s sole discretion.
      </p>
    </>
  );
};

const renderSaleCommissionBody = (v, partyLabel) => {
  const partyCaps = partyLabel.toUpperCase();
  return (
    <>
      <p>
        <strong>Commission Schedule.</strong> {partyCaps} shall pay BROKER a Brokerage Fee of {F(v.saleAgentPct ? v.saleAgentPct + '%' : null, '[5%]')} if the AGENT listed below sells the Property. In the event a Co-Broker, other than the agent(s) listed below, is involved in the sale, {partyCaps} shall pay an additional {F(v.saleCoBrokerPct ? v.saleCoBrokerPct + '%' : null, '[1%]')} fee.
      </p>
      <p>Said fees are payable upon the occurrence of any of the following conditions or other consideration for which the Property is sold, exchanged, or conveyed:</p>
      <ol style={{paddingLeft:24, margin:'8px 0 16px'}}>
        <li style={{marginBottom:8}}>The closing of the sale, Installment Sale, exchange, or conveyance of the Property during the period of this Agreement by BROKER or any other person, including but not limited to {partyCaps}, or any other agent or broker not a party to this Agreement, in accordance with the price, terms, or exchanges as set forth herein or as otherwise consented to by {partyCaps}; or</li>
        <li>The closing of the sale, Installment Sale, exchange, or conveyance of the Property within one hundred eighty (180) days after the expiration or termination of this Agreement to any prospect with whom BROKER has negotiated or to whom BROKER has exhibited the Property during the period of this Agreement, or whose name was disclosed to {partyCaps} in writing by BROKER not later than seventy-two (72) hours after the expiration or termination of this Agreement.</li>
      </ol>
      <p>The above timeframes shall be extended provided there are ongoing negotiations between {partyCaps} and a prospective purchaser beyond the expiration date.</p>
    </>
  );
};

// ════════════════════════════════════════════════════════════════════════
// TEMPLATE: LEASE
// ════════════════════════════════════════════════════════════════════════

const TEMPLATE_LEASE = (v) => [
  {
    id: 'recitals', title: 'Recitals', legalRef: '§ 1',
    body: (
      <>
        <p style={{textAlign:'center', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, color:'var(--ink-900)', marginBottom: 6}}>Lease</p>
        <p style={{textAlign:'center', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:700, fontSize:18, color:'var(--ceg-navy)', marginBottom: 18}}>Commercial Exclusive Listing Agreement</p>
        <p><strong>Date:</strong> {fmtDate(v)}</p>
        <p style={{marginTop:14}}>
          This Agreement is between <strong>Commercial Equities Group, Inc.</strong> ("BROKER") and {F(v.ownerEntity, '[OWNER NAME]')} ("LESSOR"). LESSOR grants to BROKER the exclusive right to lease real property (approximately {F(v.approxSF, '[XX,XXX]')} square feet of {F(v.spaceType, '[SPACE TYPE]')}) and improvements located at {fmtAddr(v)}, as may be legally described on the attached Exhibit A ("Property"), for the period from the date hereof through and including {fmtExpDate(v)} and shall continue on a month-to-month basis unless cancelled by LESSOR by providing thirty (30) days prior written notice to BROKER, upon the following terms and conditions, or at any other terms or conditions to which LESSOR may consent.
        </p>
      </>
    ),
  },
  noticeSection(),
  {
    id: 'obligations', title: "Lessor's Obligations", legalRef: '§ 3',
    body: (
      <>
        <p>It is agreed that LESSOR shall promptly furnish BROKER with complete information concerning any person who during the period of this Agreement makes inquiry to LESSOR regarding the lease of the Property.</p>
        <p>LESSOR further agrees to promptly notify BROKER of any notices pertaining to the Property, including any notices or information regarding hazardous waste or substances, that are received or learned during the term of this Agreement.</p>
        <p>It is further agreed that LESSOR shall permit BROKER to install a "For Lease" sign(s) or banner(s) and to remove all other "For Lease" signs from the Property, may disclose to third parties the Property's for-lease status, produce written materials and/or online marketing related to the Property, and may enter upon the Property to show it to potential tenants during the period of this Agreement. LESSOR agrees to pay for the marketing sign(s) or banner(s). BROKER shall provide the original invoice for payment.</p>
        <p>LESSOR represents that LESSOR has full legal right to lease the Property. LESSOR certifies that, as of the date of execution of this Agreement, (a) LESSOR has not received any notice of building, health or fire code violations, or notice of condemnation pertaining to the Property from any municipality or other governmental agency, and (b) no hazardous waste or substances have been used, stored, handled, or disposed of on the Property, no underground storage tanks are situated on the Property, and LESSOR has not received any notice of hazardous waste on the Property.</p>
      </>
    ),
  },
  {
    id: 'compensation', title: 'Compensation', legalRef: '§ 4',
    body: renderLeaseCommissionBody(v, 'Lessor'),
  },
  generalProvisions('lease', 5),
  signaturesSection(v.ownerEntity, 'Lessor', 6),
  agentBlock(v, 7),
  exhibitBlock(v, v.ownerEntity, 8),
];

// ════════════════════════════════════════════════════════════════════════
// TEMPLATE: SALE
// ════════════════════════════════════════════════════════════════════════

const TEMPLATE_SALE = (v) => [
  {
    id: 'recitals', title: 'Recitals', legalRef: '§ 1',
    body: (
      <>
        <p style={{textAlign:'center', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, color:'var(--ink-900)', marginBottom: 6}}>Sale</p>
        <p style={{textAlign:'center', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:700, fontSize:18, color:'var(--ceg-navy)', marginBottom: 18}}>Commercial Exclusive Listing Agreement</p>
        <p><strong>Date:</strong> {fmtDate(v)}</p>
        <p style={{marginTop:14}}>
          This Agreement is between <strong>Commercial Equities Group, Inc.</strong> ("BROKER") and {F(v.ownerEntity, '[OWNERSHIP NAME]')} ("SELLER"). SELLER grants to BROKER the exclusive right to sell or contract to sell the real property and improvements located at {fmtAddr(v)}, as may be legally described on the attached Exhibit A ("Property"), in the amount of {F(v.priceWords, '[WRITTEN-OUT PRICE]')} Dollars ({F(v.priceNumeric ? '$' + v.priceNumeric : null, '[$XXX,XXX.XX]')}), for the period from the date hereof through and including {fmtExpDate(v)} and shall continue on a month-to-month basis unless cancelled by SELLER by providing thirty (30) days prior written notice to BROKER, upon the following terms and conditions, or at any other terms or conditions to which SELLER may consent.
        </p>
      </>
    ),
  },
  noticeSection(),
  {
    id: 'obligations', title: "Seller's Obligations", legalRef: '§ 3',
    body: (
      <>
        <p>It is agreed that SELLER shall promptly furnish BROKER with complete information concerning any person who during the period of this Agreement makes inquiry to SELLER regarding the sale of the Property.</p>
        <p>SELLER agrees to provide Purchaser an Abstract of Title, Registered Property Abstract, or Title Insurance Certificate, certified to date, including proper searches covering bankruptcies and state and federal judgments and liens, and to execute or cause to be executed a deed conveying marketable title to the Property to the Purchaser, together with such further documents as may be required to consummate the sale in accordance with the terms set forth herein or to which SELLER may hereafter consent.</p>
        <p>SELLER further agrees to promptly notify BROKER of any notices pertaining to the Property, including any notices or information regarding hazardous waste or substances, that are received or learned during the term of this Agreement.</p>
        <p>It is further agreed that SELLER shall permit BROKER to install a "For Sale" sign(s) or banner(s) and to remove all other "For Sale" signs from the Property, may disclose to third parties the Property's for-sale status, produce written materials and/or online marketing related to the Property, and may enter upon the Property to show it to potential purchasers during the period of this Agreement. SELLER agrees to pay for the marketing sign(s) or banner(s). BROKER shall provide the original invoice for payment.</p>
        <p>SELLER represents that SELLER has full legal right to sell the Property. SELLER certifies that, as of the date of execution of this Agreement, (a) SELLER has not received any notice of building, health or fire code violations, or notice of condemnation pertaining to the Property from any municipality or other governmental agency, and (b) no hazardous waste or substances have been used, stored, handled, or disposed of on the Property, no underground storage tanks are situated on the Property, and SELLER has not received any notice of hazardous waste on the Property.</p>
      </>
    ),
  },
  {
    id: 'compensation', title: 'Compensation', legalRef: '§ 4',
    body: renderSaleCommissionBody(v, 'Seller'),
  },
  generalProvisions('sale', 5),
  signaturesSection(v.ownerEntity, 'Seller', 6),
  agentBlock(v, 7),
  exhibitBlock(v, v.ownerEntity, 8),
];

// ════════════════════════════════════════════════════════════════════════
// TEMPLATE: SALE OR LEASE (combined)
// ════════════════════════════════════════════════════════════════════════

const TEMPLATE_LEASE_SALE = (v) => [
  {
    id: 'recitals', title: 'Recitals', legalRef: '§ 1',
    body: (
      <>
        <p style={{textAlign:'center', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, color:'var(--ink-900)', marginBottom: 6}}>Sale or Lease</p>
        <p style={{textAlign:'center', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:700, fontSize:18, color:'var(--ceg-navy)', marginBottom: 18}}>Commercial Exclusive Listing Agreement</p>
        <p><strong>Date:</strong> {fmtDate(v)}</p>
        <p style={{marginTop:14}}>
          This Agreement is between <strong>Commercial Equities Group, Inc.</strong> ("BROKER") and {F(v.ownerEntity, '[OWNER NAME]')} ("OWNER"). OWNER grants to BROKER the exclusive right to sell, contract to sell, or lease the real property and improvements located at {fmtAddr(v)}, as may be legally described on the attached Exhibit A ("Property"). The term of this Agreement shall commence on the date hereof through and including {fmtExpDate(v)} and shall continue on a month-to-month basis unless cancelled by OWNER by providing thirty (30) days prior written notice to BROKER, upon the following terms and conditions, or at any other terms or conditions to which OWNER may consent. The Property is offered for sale at {F(v.priceWords, '[WRITTEN-OUT PRICE]')} Dollars ({F(v.priceNumeric ? '$' + v.priceNumeric : null, '[$XXX,XXX.XX]')}) and for lease at {F(v.askingLeaseRate ? '$' + v.askingLeaseRate : null, '[$X.XX]')} per square foot per year, or at any other price or terms to which OWNER may consent.
        </p>
        <p style={{marginTop:14}}>
          <strong>Either or Both Transactions.</strong> The Property shall be marketed by BROKER for both purposes during the term of this Agreement, and OWNER shall determine, in OWNER's sole discretion, whether to accept any sale or lease offer presented. Upon the closing of either a sale or the full execution of a lease, the marketing of the Property for the alternative transaction shall cease and the corresponding commission structure below shall apply.
        </p>
      </>
    ),
  },
  noticeSection(),
  {
    id: 'obligations', title: "Owner's Obligations", legalRef: '§ 3',
    body: (
      <>
        <p>It is agreed that OWNER shall promptly furnish BROKER with complete information concerning any person who during the period of this Agreement makes inquiry to OWNER regarding the sale or lease of the Property.</p>
        <p>In the event of a sale, OWNER agrees to provide Purchaser an Abstract of Title, Registered Property Abstract, or Title Insurance Certificate, certified to date, including proper searches covering bankruptcies and state and federal judgments and liens, and to execute or cause to be executed a deed conveying marketable title to the Property to the Purchaser, together with such further documents as may be required to consummate the sale in accordance with the terms set forth herein or to which OWNER may hereafter consent.</p>
        <p>OWNER further agrees to promptly notify BROKER of any notices pertaining to the Property, including any notices or information regarding hazardous waste or substances, that are received or learned during the term of this Agreement.</p>
        <p>It is further agreed that OWNER shall permit BROKER to install "For Sale" and/or "For Lease" sign(s) or banner(s) and to remove all other for-sale or for-lease signs from the Property, may disclose to third parties the Property's for-sale and for-lease status, produce written materials and/or online marketing related to the Property, and may enter upon the Property to show it to potential purchasers and tenants during the period of this Agreement. OWNER agrees to pay for the marketing sign(s) or banner(s). BROKER shall provide the original invoice for payment.</p>
        <p>OWNER represents that OWNER has full legal right to sell and lease the Property. OWNER certifies that, as of the date of execution of this Agreement, (a) OWNER has not received any notice of building, health or fire code violations, or notice of condemnation pertaining to the Property from any municipality or other governmental agency, and (b) no hazardous waste or substances have been used, stored, handled, or disposed of on the Property, no underground storage tanks are situated on the Property, and OWNER has not received any notice of hazardous waste on the Property.</p>
      </>
    ),
  },
  {
    id: 'sale-compensation', title: 'Sale Compensation', legalRef: '§ 4',
    body: (
      <>
        <p><strong>Sale Commission.</strong> If the Property is sold, OWNER shall pay BROKER a Brokerage Fee of {F(v.saleAgentPct ? v.saleAgentPct + '%' : null, '[5%]')} of the gross sale price if the AGENT listed below sells the Property. In the event a Co-Broker, other than the agent(s) listed below, is involved in the sale, OWNER shall pay an additional {F(v.saleCoBrokerPct ? v.saleCoBrokerPct + '%' : null, '[1%]')} fee.</p>
        <p>Said sale fees are payable upon the occurrence of any of the following conditions or other consideration for which the Property is sold, exchanged, or conveyed:</p>
        <ol style={{paddingLeft:24, margin:'8px 0 16px'}}>
          <li style={{marginBottom:8}}>The closing of the sale, Installment Sale, exchange, or conveyance of the Property during the period of this Agreement by BROKER or any other person, including but not limited to OWNER, or any other agent or broker not a party to this Agreement, in accordance with the price, terms, or exchanges as set forth herein or as otherwise consented to by OWNER; or</li>
          <li>The closing of the sale, Installment Sale, exchange, or conveyance of the Property within one hundred fifty (150) days after the expiration or termination of this Agreement to any prospect with whom BROKER has negotiated or to whom BROKER has exhibited the Property during the period of this Agreement, or whose name was disclosed to OWNER in writing by BROKER not later than seventy-two (72) hours after the expiration or termination of this Agreement.</li>
        </ol>
      </>
    ),
  },
  {
    id: 'lease-compensation', title: 'Lease Compensation', legalRef: '§ 5',
    body: (
      <>
        {v.leaseStructure === OPT1 && (
          <p>
            <strong>Option 1 — Flat Per Square Foot (typical for Office).</strong> If the Property is leased, leases of twelve (12) months or less shall be one (1) month's gross rent. Leases beyond twelve (12) months shall be {F(v.opt1Rate ? '$' + v.opt1Rate : null, '[$1.00]')} per square foot per year. If an outside broker brings a tenant to the Property and a lease is entered into, the commission for the lease shall be {F(v.opt1OutsideMult ? v.opt1OutsideMult + '%' : null, '[150%]')} of the above schedule. It is expected that Landlord will negotiate renewal leases with Tenant, but Landlord, may at its sole discretion, request, in writing, for Broker to negotiate a lease renewal with an existing Tenant. Upon full execution of lease renewal Broker will be paid {F(v.opt1RenewalRate ? '$' + v.opt1RenewalRate : null, '[$0.50]')} per square foot per year plus any fees charged by an outside broker as agreed to in advance by Landlord.
          </p>
        )}
        {v.leaseStructure === OPT2 && (
          <p>
            <strong>Option 2 — Graduated Percentage of Net Rent (typical for Industrial).</strong> If the Property is leased, OWNER shall pay BROKER a Brokerage Fee of {F(v.opt2Y1 ? v.opt2Y1 + '%' : null, '[7%]')} of Year One Net Rent, {F(v.opt2Y2 ? v.opt2Y2 + '%' : null, '[6%]')} of Year Two Net Rent, {F(v.opt2Y3 ? v.opt2Y3 + '%' : null, '[5%]')} of Year Three Net Rent, {F(v.opt2Y4 ? v.opt2Y4 + '%' : null, '[4%]')} of Year Four Net Rent, {F(v.opt2Y5plus ? v.opt2Y5plus + '%' : null, '[3%]')} of Year Five Net Rent, and {F(v.opt2Y5plus ? v.opt2Y5plus + '%' : null, '[3%]')} of Net Rent for each year thereafter for the initial lease term, for a direct deal with the agent(s) listed below. In the event a Co-Broker, other than the agent(s) listed below, is engaged, OWNER shall pay BROKER {F(v.opt2CoBrokerMult ? v.opt2CoBrokerMult + '%' : null, '[150%]')} of the above commission schedule.
          </p>
        )}
        {!v.leaseStructure && (
          <p style={{padding:'12px 14px', background:'var(--warning-bg)', borderRadius:8, color:'#6b4900', fontSize:13}}>
            ⚠ Lease commission structure not yet selected. Pick Option 1 (Office) or Option 2 (Industrial) in the form to populate this clause.
          </p>
        )}
        <p style={{marginTop:14}}>
          <strong>Payment Terms (applies to either option above).</strong> The leasing commission shall be paid in the following manner: {F(v.paySplitExec ? v.paySplitExec + '%' : null, '[50%]')} upon full execution of a lease and {F(v.paySplitCommence ? v.paySplitCommence + '%' : null, '[50%]')} upon lease commencement. If an outside broker requests a higher fee as part of any leasing proposal, notice shall be given to OWNER of the request, and OWNER may accept or reject payment of the higher fee at OWNER's sole discretion.
        </p>
        <p style={{marginTop:14}}>Said lease fees are payable upon the occurrence of any of the following conditions:</p>
        <ol style={{paddingLeft:24, margin:'8px 0 16px'}}>
          <li style={{marginBottom:8}}>The lease of the Property during the period of this Agreement by BROKER or any other broker not a party to this Agreement; or</li>
          <li>If within one hundred eighty (180) days after the end of this Agreement, OWNER leases or agrees to lease the Property to anyone who has made an affirmative showing of interest in the Property by responding to an advertisement or by contacting BROKER, provided that the name of the prospect was disclosed to OWNER in writing by BROKER not later than seventy-two (72) hours after the expiration or termination of this Agreement.</li>
        </ol>
        <p>The above timeframes shall be extended provided there are ongoing negotiations between OWNER and a prospective purchaser or tenant beyond the expiration date.</p>
      </>
    ),
  },
  generalProvisions('both', 6),
  signaturesSection(v.ownerEntity, 'Owner', 7),
  agentBlock(v, 8),
  exhibitBlock(v, v.ownerEntity, 9),
];

// ════════════════════════════════════════════════════════════════════════
// DEMO VALUES — for the "Prefill demo data" button
// ════════════════════════════════════════════════════════════════════════

const DEMO_LEASE = {
  propertyAddress: '2400 Wacker Dr',
  propertyCity: 'Minneapolis',
  propertyZip: '55401',
  approxSF: '14,200',
  spaceType: 'Office',
  ownerEntity: 'Wacker Riverfront LLC',
  signatoryName: 'Mark Allen',
  signatoryTitle: 'Managing Member',
  ownerEmail: 'mark@wackerriver.com',
  ownerPhone: '(612) 555-0188',
  effectiveDate: '2026-05-13',
  leaseStructure: OPT1,
  broker: 'Brian Potratz',
  brokerEmail: 'brian@cegspaces.com',
  legalDescription: 'Lot 4, Block 2, Wacker Riverfront Addition, Hennepin County, Minnesota.',
  parcelId: '17-029-24-44-0089',
};

const DEMO_SALE = {
  propertyAddress: '1845 W Industrial Blvd',
  propertyCity: 'St. Paul',
  propertyZip: '55114',
  ownerEntity: 'Industrial Blvd Holdings LP',
  signatoryName: 'Diane Houghton',
  signatoryTitle: 'General Partner',
  ownerEmail: 'diane@industrialblvd.com',
  ownerPhone: '(651) 555-0144',
  effectiveDate: '2026-05-13',
  priceNumeric: '2,450,000',
  priceWords: 'Two Million Four Hundred Fifty Thousand',
  broker: 'Jeff Salzbrun',
  brokerEmail: 'jeff@cegspaces.com',
  legalDescription: 'Lot 7, Block 1, Industrial Park Second Addition, Ramsey County, Minnesota.',
  parcelId: '29-29-23-21-0007',
};

const DEMO_LEASE_SALE = {
  ...DEMO_LEASE,
  propertyAddress: '8200 Penn Ave S',
  propertyCity: 'Bloomington',
  propertyZip: '55431',
  spaceType: 'Industrial Flex',
  ownerEntity: 'Penn Ave Capital LLC',
  signatoryName: 'Curtis Walsh',
  signatoryTitle: 'Manager',
  ownerEmail: 'curtis@pennavecapital.com',
  ownerPhone: '(952) 555-0212',
  priceNumeric: '3,750,000',
  priceWords: 'Three Million Seven Hundred Fifty Thousand',
  askingLeaseRate: '12.50',
  leaseStructure: OPT2,
  broker: 'Brady Erickson',
  brokerEmail: 'brady@cegspaces.com',
  legalDescription: 'Tract A, Registered Land Survey No. 1147, Hennepin County, Minnesota.',
  parcelId: '07-027-24-13-0014',
};

// ════════════════════════════════════════════════════════════════════════
// REGISTER (overwrites the placeholder entries seeded by data.jsx)
// ════════════════════════════════════════════════════════════════════════

window.FORM_SCHEMAS['list-lease']       = SCHEMA_LEASE;
window.FORM_SCHEMAS['list-sale']        = SCHEMA_SALE;
window.FORM_SCHEMAS['list-lease-sale']  = SCHEMA_LEASE_SALE;

window.DRAFT_TEMPLATES['list-lease']      = TEMPLATE_LEASE;
window.DRAFT_TEMPLATES['list-sale']       = TEMPLATE_SALE;
window.DRAFT_TEMPLATES['list-lease-sale'] = TEMPLATE_LEASE_SALE;

window.DEMO_VALUES['list-lease']      = DEMO_LEASE;
window.DEMO_VALUES['list-sale']       = DEMO_SALE;
window.DEMO_VALUES['list-lease-sale'] = DEMO_LEASE_SALE;
