import React from 'react';
import superagent from 'superagent';
import { fromUnixTime, formatDistanceToNow } from "date-fns";
import { formatInTimeZone } from 'date-fns-tz';

import * as ApiUtils from '../CloudApi/ApiUtils.js';
import constants, { DEFAULT_TIMEZONE } from '../CloudApi/Constants.js';
import WaxIdBitField from '../Fabricator/WaxIdBitField.jsx';
import ToolPathDownloadButton from '../Fabricator/ToolPathDownloadButton.jsx';
import ShopifyOrderComponent from './ShopifyOrderComponent.jsx';
import ScanRequestComponent from '../Fabricator/ScanRequestComponent.jsx';
import ScanRequestsTable from '../Fabricator/ScanRequestsTable.jsx';
import ClickableTableRow from '../Util/ClickableTableRow.jsx';
import ApiButtonModal from '../CloudApi/ApiButtonModal.jsx';
import BigApiErrorMessage from '../CloudApi/BigApiErrorMessage.jsx';
import BigShipmentInventoryCards from '../BigLogistics/BigShipmentInventoryCards.jsx';
import BigShipmentInventorySlotsTable from '../BigLogistics/BigShipmentInventorySlotsTable.jsx';
import BigOrderTableCells from './BigOrderTableCells.jsx';

import { Header, Message, Icon, Button, Table, Label, Segment, Modal, Form, Statistic, Radio, Grid, Dropdown, Image, Card, Divider } from 'semantic-ui-react'

/**
 * HACK HACK HACK
 * 
 * I am splitting this off into a component to prevent an even propagation bug.
 * 
 * In Semantic UI React, the space bar triggers a click on the Dropdown trigger.
 */
class BigShipmentHoldButtonModal extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            shipmentHoldReason: "",
            shipmentHoldNotes: "",
        };
        this.onChange = this.onChange.bind(this);
        this.onConfirm = this.onConfirm.bind(this);
    }

    onChange(e, { name, value }) {
        this.setState({ [name]: value })
    }

    onConfirm() {
        this.props.onConfirm(this.state.shipmentHoldReason, this.state.shipmentHoldNotes);
    }

    handleKeyDown(event) {
        if (event.key === ' ') {
            event.stopPropagation();
        }
    }

    render() {
        return (
            <ApiButtonModal as="dropdown" color="violet" size="small" icon="pause" text="Hold Shipment" cancel modalIcon="pause" modalButtonText="OK, add a hold to this order" onConfirm={this.onConfirm}>
                This will add a hold to the order and will prevent anyone from shipping it via BigShipper.
                <Form>
                    <Form.Group widths="equal">
                        <Form.Select width={10} size="medium" label="Hold Reason" name="shipmentHoldReason"
                            options={this.props.schemas.BigOrderShipmentHoldReasonsOptions}
                            value={this.state.shipmentHoldReason} onChange={this.onChange} />
                    </Form.Group>

                    <Form.Group widths="equal">
                        <Form.Input width={10} size="medium" label="Extra Notes" name="shipmentHoldNotes" value={this.state.shipmentHoldNotes} onChange={this.onChange} onKeyDown={this.handleKeyDown} />
                    </Form.Group>
                </Form>
            </ApiButtonModal>
        );
    }

}

export default class BigOrderComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            loadingChecklist: false,
            showNextActionModal: false,
            showCreateJobModal: false,
            showIPDScanRequestModal: false,
            priority: 0,
            inventorySlots: [],
            shipmentHoldNotes: "",
            shipmentHoldReason: "",
            expandedHistoryGroups: {}, // Track which repeated message groups are expanded
        };
        this.onChange = this.onChange.bind(this);
        this.toggleHistoryGroup = this.toggleHistoryGroup.bind(this);
    }

    toggleHistoryGroup(groupIndex) {
        this.setState(prevState => ({
            expandedHistoryGroups: {
                ...prevState.expandedHistoryGroups,
                [groupIndex]: !prevState.expandedHistoryGroups[groupIndex]
            }
        }));
    }

    async componentDidMount() {
        this.setState({
            newShippingServiceLevel: this.props.bigOrder.shippingServiceLevel,
            newPriority: this.props.bigOrder.priority,
            newIpd: this.props.bigOrder.ipd
        });

        if (!this.props.asTableRow) {
            await this.onLoadInventory();
        }
    }

    async onUpdateChecklist() {
        this.setState({ loadingChecklist: true });

        try {
            let res = await superagent.get(`/api/admin/shop/order/${this.props.bigOrder.id}/checklist`);
        } catch (e) {
            if (e.status === 422) {
                this.props.bigOrder.checklistResult = e.response.body;
            }
        }
        if (!this.props.asTableRow) {
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        }
    }

    async onSynchronizeLineItems() {
        this.setState({ loading: true });

        try {
            let res = await superagent.get(`/api/admin/shop/order/${this.props.bigOrder.id}/sync_line_items`);
        } catch (e) {
            if (e.status === 422) {
                this.props.bigOrder.checklistResult = e.response.body;
            }
        }
        if (!this.props.asTableRow) {
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        }
    }

    async onCreateShipment(shipmentGroupId) {
        this.setState({ loading: true });
        try {
            console.log("Creating shipment for group", shipmentGroupId);
            let res = await superagent.post(`/api/admin/shipper/shipment`).send({
                bigOrderId: this.props.bigOrder.id,
                shipmentGroupId
            });
            window.location.href = `/shipper/shipment/${res.body.id}`;
        } catch (e) {
            console.log(e);
        }
        this.setState({ loading: false });
    }


    async onSynchronizeBigOrder() {
        this.setState({ loading: true });

        try {
            let res = await superagent.get(`/api/admin/shop/order/${this.props.bigOrder.id}/sync`);
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        } catch (e) {
            console.log(e);
        }

        this.setState({ loading: false });
    }


    async onDeleteBigOrder() {
        this.setState({ loading: true });

        try {
            const result = await superagent.delete(`/api/admin/shop/order/${this.props.bigOrder.id}`).accept('json');
        } catch (e) {
            console.log(e);
        }

        window.location.href = `/shop/orders`;
        this.setState({ loading: false });
    }

    onChange(e, { name, value }) {
        e.stopPropagation();
        e.preventDefault();
        this.setState({ [name]: value })
    }

    showNextActionModal(i, e) {
        this.setState({ showNextActionModal: true });
    }

    closeNextActionModal(i, e) {
        this.setState({ showNextActionModal: false });
    }

    async onNextAction(e) {
        e.preventDefault();

        if (!this.props.bigOrder.checklistResult) {
            return;
        }

        this.setState({ loading: true, showNextActionModal: false });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                action: this.props.bigOrder.checklistResult.nextAction
            });

            this.props.bigOrder.checklistResult.nextAction = null;

            if (!this.props.asTableRow) {
                window.location.href = `/shop/order/${this.props.bigOrder.id}`;
            }
        } catch (e) {
            window.alert("Error sending scan request email");
            console.error(e);
        }

        this.setState({ loading: false });
    }

    showCreateJobModal() {
        this.setState({ priority: 0, showCreateJobModal: true });
    }

    closeCreateJobModal(i, e) {
        this.setState({ showCreateJobModal: false, error: null });
    }

    async onCreateJob(e) {
        e.preventDefault();
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                priority: this.state.priority,
                action: this.props.bigOrder.checklistResult.nextAction
            });
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        } catch (e) {
            window.alert("Error sending scan request email");
            console.error(e);
        }

        this.setState({ loading: false, showNextActionModal: false });
    }

    async onCreateReturnLabel(shipmentId) {
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shipper/shipment/${shipmentId}`).send({
                action: "AdminCreateReturnLabel"
            });

            this.setState({ returnLabel: res.body, loading: false });

        } catch (e) {
            this.setState({ returnLabelError: e });
            console.error(e);
        }

        this.setState({ loading: false });
    }

    async onRegenerateScanRequest(e) {
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                action: "AdminRegenerateScanRequest"
            });
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        } catch (e) {
            window.alert("Error sending scan request email");
            console.error(e);
        }

        this.setState({ loading: false });
    }

    async onResendScanResultEmail() {
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                action: "ResendScanResultEmail"
            });
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
            this.setState({ loading: false });
        } catch (ex) {
            console.log(ex.status);
            console.log(ex.response.body);
            this.setState({ error: ex.response.body.message, loading: false });
            console.error(ex);
        }
    }

    async onAdminOverrideIpd() {
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                action: "AdminOverrideIPD",
                ipd: this.state.newIpd
            });
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
            this.setState({ loading: false });
        } catch (ex) {
            console.log(ex.status);
            console.log(ex.response.body);
            this.setState({ error: ex.response.body.message, loading: false });
            console.error(ex);
        }
    }

    async onAdminAddShippingHold(shipmentHoldReason, shipmentHoldNotes) {
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                action: "AdminAddShippingHold",
                shipmentHold: {
                    reason: shipmentHoldReason,
                    notes: shipmentHoldNotes
                }
            });
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        } catch (ex) {
            console.log(ex.status);
            console.log(ex.response.body);
            this.setState({ error: ex.response.body.message });
            console.error(ex);
        }
        this.setState({ loading: false });
    }

    async onAdminRemoveShippingHold() {
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                action: "AdminRemoveShippingHold"
            });
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        } catch (ex) {
            console.log(ex.status);
            console.log(ex.response.body);
            this.setState({ error: ex.response.body.message });
            console.error(ex);
        }
        this.setState({ loading: false });
    }

    async onAdminUpdatePriority() {
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                action: "AdminSetPriority",
                priority: this.state.newPriority
            });
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        } catch (ex) {
            console.log(ex.status);
            console.log(ex.response.body);
            this.setState({ error: ex.response.body.message });
            console.error(ex);
        }
        this.setState({ loading: false });
    }

    async onAdminSetShippingServiceLevel() {
        this.setState({ loading: true });
        try {
            let res = await superagent.put(`/api/admin/shop/order/${this.props.bigOrder.id}`).send({
                action: "AdminSetShippingServiceLevel",
                shippingServiceLevel: this.state.newShippingServiceLevel
            });
            window.location.href = `/shop/order/${this.props.bigOrder.id}`;
        } catch (ex) {
            console.log(ex.status);
            console.log(ex.response.body);
            this.setState({ error: ex.response.body.message });
            console.error(ex);
        }
        this.setState({ loading: false });
    }

    async onLoadInventory() {
        this.setState({ loading: true });
        try {
            let res = await superagent.get(`/api/admin/shop/order/${this.props.bigOrder.id}/shipping_summary`);
            console.log(res.body);
            this.setState({ shipping_summary: res.body });

            let res2 = await superagent.get(`/api/admin/shop/order/${this.props.bigOrder.id}/shipments`);
            this.setState({ shipments: res2.body.items, loading: false });
        } catch (ex) {
            console.log(ex.status);
            console.log(ex.response.body);
            this.setState({ error: ex.response.body.message, loading: false });
            console.error(ex);
        }
    }

    renderReturnLabelModal(shipmentId) {
        let modalContent = null;

        if (this.state.returnLabel) {
            const shippingLabel = this.state.returnLabel;
            const trackingNumber = shippingLabel.tracking_number || shippingLabel.trackingNumber;
            const trackingUrlProvider = shippingLabel.tracking_url_provider || shippingLabel.trackingUrlProvider;
            const uploadLabelUrl = shippingLabel.upload_label_url || shippingLabel.uploadLabelUrl;
            const rateAmount = shippingLabel.rate_amount || shippingLabel.rateAmount;
            const rateCurrency = shippingLabel.rate_currency || shippingLabel.rateCurrency || "USD";
            const originalShipment = this.state.shipments?.find(s => s.id === shipmentId);
            const originalShippingLabel = originalShipment?.currentShippingLabel;
            const originalTrackingNumber = originalShippingLabel?.tracking_number || originalShippingLabel?.trackingNumber;
            const originalTrackingUrl = originalShippingLabel?.tracking_url_provider || originalShippingLabel?.trackingUrlProvider;
            modalContent = (
                <Grid celled columns="2">
                    <Grid.Column width={9}>
                        <Header as="h3">Copy the tracking number and pdf link into Shopify...</Header>
                        <Table celled>
                            <Table.Body>
                                <Table.Row>
                                    <Table.Cell>Return Tracking #</Table.Cell>
                                    <Table.Cell>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: '0.5em' }}>
                                            <a style={{ 'textDecoration': 'underline' }} href={trackingUrlProvider}>{trackingNumber}</a>
                                            <Button size="tiny" icon="copy" onClick={() => { navigator.clipboard.writeText(trackingNumber) }} />
                                        </div>
                                    </Table.Cell>
                                </Table.Row>
                                {trackingUrlProvider && <Table.Row>
                                    <Table.Cell>Return Tracking Link</Table.Cell>
                                    <Table.Cell>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: '0.5em' }}>
                                            <a style={{ 'textDecoration': 'underline', wordBreak: 'break-all' }} href={trackingUrlProvider}>{trackingUrlProvider}</a>
                                            <Button size="tiny" icon="copy" style={{ flexShrink: 0 }} onClick={() => { navigator.clipboard.writeText(trackingUrlProvider) }} />
                                        </div>
                                    </Table.Cell>
                                </Table.Row>}
                                <Table.Row>
                                    <Table.Cell>Return PDF File Link</Table.Cell>
                                    <Table.Cell>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: '0.5em' }}>
                                            <a style={{ 'textDecoration': 'underline' }} href={uploadLabelUrl}>{uploadLabelUrl}</a>
                                            <Button size="tiny" icon="copy" onClick={() => { navigator.clipboard.writeText(uploadLabelUrl) }} />
                                        </div>
                                    </Table.Cell>
                                </Table.Row>
                                {rateAmount && <Table.Row>
                                    <Table.Cell>Return Label Cost</Table.Cell>
                                    <Table.Cell>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: '0.5em' }}>
                                            <span>{rateCurrency === "USD" ? "US" : rateCurrency}${parseFloat(rateAmount).toFixed(2)}</span>
                                        </div>
                                    </Table.Cell>
                                </Table.Row>}
                                <Table.Row>
                                    <Table.Cell>Order</Table.Cell>
                                    <Table.Cell>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: '0.5em' }}>
                                            <span>{this.props.bigOrder.shopifyOrderName} — {this.props.shopifyOrder?.customer?.first_name} {this.props.shopifyOrder?.customer?.last_name}</span>
                                            <Button size="tiny" icon="copy" onClick={() => { navigator.clipboard.writeText(this.props.bigOrder.shopifyOrderName) }} />
                                        </div>
                                    </Table.Cell>
                                </Table.Row>
                                {originalTrackingNumber && <Table.Row>
                                    <Table.Cell>Original Tracking #</Table.Cell>
                                    <Table.Cell>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: '0.5em' }}>
                                            <a style={{ 'textDecoration': 'underline' }} href={originalTrackingUrl}>{originalTrackingNumber}</a>
                                            <Button size="tiny" icon="copy" onClick={() => { navigator.clipboard.writeText(originalTrackingNumber) }} />
                                        </div>
                                    </Table.Cell>
                                </Table.Row>}
                                {originalTrackingUrl && <Table.Row>
                                    <Table.Cell>Original Tracking Link</Table.Cell>
                                    <Table.Cell>
                                        <div style={{ display: 'flex', alignItems: 'center', gap: '0.5em' }}>
                                            <a style={{ 'textDecoration': 'underline', wordBreak: 'break-all' }} href={originalTrackingUrl}>{originalTrackingUrl}</a>
                                            <Button size="tiny" icon="copy" style={{ flexShrink: 0 }} onClick={() => { navigator.clipboard.writeText(originalTrackingUrl) }} />
                                        </div>
                                    </Table.Cell>
                                </Table.Row>}
                            </Table.Body>
                        </Table>
                        <Button color="green" target='_new' href={`https://admin.shopify.com/store/bigscreenvr/orders/${this.props.bigOrder.shopifyOrderId}/return`} size="small"><Icon name='external' />Open Shopify Return</Button>
                    </Grid.Column>
                    <Grid.Column width={7}>
                        <iframe ref={this.iframeRef} src={`/file/${encodeURIComponent(uploadLabelUrl)}#toolbar=0&navpanes=0&scrollbar=0`}
                            title="Shippo label" width="333.333" height="500"></iframe>
                    </Grid.Column>
                </Grid>
            );
        } else {
            modalContent = (
                <Segment loading={this.state.loading}>
                    <Message icon>
                        {this.state.loading && <Icon name='circle notched' />}
                        <Message.Content>
                            <Message.Header>Create Return Label?</Message.Header>
                            This will take several seconds...
                        </Message.Content>
                    </Message>
                    <Button color="green" onClick={() => this.onCreateReturnLabel(shipmentId)}>Create Return Label</Button>
                </Segment>
            );
        }

        return (
            <ApiButtonModal color="purple" icon="undo" size="small" text="Create Return Label" cancel modalIcon="undo" modalButtonText="OK, I'm Done">
                {this.state.returnLabelError && <BigApiErrorMessage error={this.state.returnLabelError} />}
                {modalContent}
            </ApiButtonModal>
        );
    }

    renderTitle() {
        const createdAtDateTime = Date.parse(this.props.shopifyOrder.created_at);
        const created = formatInTimeZone(createdAtDateTime, DEFAULT_TIMEZONE, 'PPPp z');

        const title = (
            <Header as="h2">
                📦 Order <span style={{ textDecoration: "underline" }}>{this.props.bigOrder.shopifyOrderName}</span> for <a style={{ textDecoration: "underline" }} href={`/account/${this.props.bigOrder.ownerBigscreenAccountId}`}>{this.props.shopifyOrder.customer.first_name} {this.props.shopifyOrder.customer.last_name}</a>
            </Header>
        );
        const createdAt = formatInTimeZone(createdAtDateTime, DEFAULT_TIMEZONE, 'PPPp z');
        const fromNow = formatDistanceToNow(createdAtDateTime, { addSuffix: true });

        let shopifyButton = (this.props.bigOrder.origin === "Shopify") ? <Button color="green" target='_new' href={`https://admin.shopify.com/store/bigscreenvr/orders/${this.props.bigOrder.shopifyOrderId}`} size="small"><Icon name='external' />See Shopify Info</Button> : null

        const orderActionsAllowed = this.props.bigOrder.state !== "Shipped" && this.props.bigOrder.state !== "Cancelled";

        return (
            <div style={{ display: "flex" }}>
                <div style={{ flex: 3 }}>
                    {title}
                    <p>Created: {createdAt} ({fromNow})</p>
                </div>
                <div style={{ flex: 1, textAlign: "right", verticalAlign: "center" }}>
                    <Dropdown direction='left' icon={null} closeOnBlur openOnFocus={false} trigger={
                        <Button color="blue">📦 Big Order Actions...</Button>
                    }>
                        <Dropdown.Menu>
                            <Dropdown.Header as="h2" content="📦 Shipping Changes" />

                            {orderActionsAllowed && <>
                                {!this.props.bigOrder.shipmentHold && <BigShipmentHoldButtonModal schemas={this.props.schemas} onConfirm={this.onAdminAddShippingHold.bind(this)} />}

                                <ApiButtonModal as="dropdown" color="blue" size="small" icon="sort" text="Set Priority" cancel modalIcon="sort" modalButtonText="OK, set priority" onConfirm={this.onAdminUpdatePriority.bind(this)}>
                                    This will update the order's priority -- higher priority will be shipped sooner.
                                    <Form>
                                        <Form.Group inline widths="equal">
                                            <Form.Input width={10} size="medium" name="newPriority" value={this.state.newPriority} onChange={this.onChange} />
                                        </Form.Group>
                                    </Form>
                                </ApiButtonModal>

                                <ApiButtonModal as="dropdown" color="teal" size="small" icon="eye" text="Override IPD" cancel modalIcon="eye" modalButtonText="OK, update the ipd" onConfirm={this.onAdminOverrideIpd.bind(this)}>
                                    This will force the customer's IPD to be updated.
                                    <Form>
                                        <Form.Group inline widths="equal">
                                            <Form.Input width={10} size="medium" name="newIpd" value={this.state.newIpd} onChange={this.onChange} />
                                        </Form.Group>
                                    </Form>
                                </ApiButtonModal>

                                <ApiButtonModal as="dropdown" color="orange" size="small" icon="shipping fast" text="Set Shipping Service Level" cancel modalIcon="shipping fast" modalButtonText="OK, set the shipping service level" onConfirm={this.onAdminSetShippingServiceLevel.bind(this)}>
                                    <strong>Admin only.</strong> Changing this option may cause BigShipper to use a faster shipping option, if available.
                                    <br />
                                    <br />
                                    <Form>
                                        <Form.Group widths="equal">
                                            <Form.Select width={10} size="medium" label="New Shipping Service Level" name="newShippingServiceLevel"
                                                options={this.props.schemas.BigOrderShippingServiceLevelsOptions}
                                                value={this.state.newShippingServiceLevel} onChange={this.onChange} />
                                        </Form.Group>
                                    </Form>
                                </ApiButtonModal>

                                <Dropdown.Divider />
                                <Dropdown.Header as="h2" content="📸 Scan Requests" />
                                <ApiButtonModal as="dropdown" color="black" size="small" icon="cog" text="Regenerate scan request" cancel modalIcon="cog" modalButtonText="OK, regenerate the scan request" onConfirm={this.onRegenerateScanRequest.bind(this)}>
                                    The following will happen when you resend a scan request:
                                    <ul>
                                        <li>All existing scan requests for this customer <strong>will be revoked</strong>.</li>
                                        <li>A new scan request will be generated for this customer.</li>
                                        <li>An email will be sent to the customer with a new link for them to start the scanning process.</li>
                                        <li>Any jobs attached to this order <strong>will be marked as "destroyed"</strong>.</li>
                                        <li>The order status will be set to <Label>WaitUntilJobComplete</Label>.</li>
                                    </ul>
                                </ApiButtonModal>

                                <ApiButtonModal as="dropdown" color="black" size="small" icon="refresh" text="Send IPD Change Email" cancel modalIcon="eye" modalButtonText="OK, send the email" onConfirm={this.onResendScanResultEmail.bind(this)}>
                                    This will send a link so the customer can change their IPD.
                                    <ul>
                                        <li>This will only work if the customer has already completed a scan request.</li>
                                    </ul>
                                </ApiButtonModal>
                            </>}

                            <Dropdown.Divider />
                            <Dropdown.Header as="h2" content="⚠️ Admin Tools" />
                            <Dropdown.Item>
                                <Button loading={this.state.loadingChecklist} onClick={this.onUpdateChecklist.bind(this)} color="blue" size="small" fluid><Icon name='redo' />Update Checklist</Button>
                            </Dropdown.Item>

                            <Dropdown.Item>
                                <Button loading={this.state.loadingChecklist} onClick={this.onSynchronizeLineItems.bind(this)} color="green" size="small" fluid><Icon name='refresh' />Synchronize Line Items</Button>
                            </Dropdown.Item>

                            <Dropdown.Divider />
                            <Dropdown.Header as="h2" icon="warning sign" content="Danger Zone" />
                            <Dropdown.Item>
                                <ApiButtonModal color="red" size="small" icon="trash" text="Delete Big Order" cancel modalIcon="trash" modalButtonText="Ok, Delete Big Order" onConfirm={this.onDeleteBigOrder.bind(this)}>
                                    This will delete the Big Order.
                                </ApiButtonModal>
                            </Dropdown.Item>

                            <Dropdown.Divider />
                            <Dropdown.Header as="h2" icon="external" content="External Links" />
                            <Dropdown.Item>
                                {shopifyButton}
                            </Dropdown.Item>
                        </Dropdown.Menu>
                    </Dropdown>
                </div>
            </div>
        );
    }

    renderBanners() {
        const banners = [];

        if (this.props.shopifyOrder.THIS_SHOPIFY_ORDER_WAS_DELETED) {
            banners.push(<Segment inverted color="red">
                    <Icon name="trash" />The underlying shopify order was deleted<Icon name="trash" />
                </Segment>)
        }
        if (this.props.shopifyOrder.tags.includes("test order") || this.props.shopifyOrder.test === true) {
            banners.push(
                <Segment inverted color="orange">
                    <Icon name="dont" />This is a test order. BE CAREFUL WITH SHIPPING THIS ORDER!<Icon name="dont" />
                </Segment>
            );
        }

        return <>
            {banners}
        </>;
    }

    renderShopifyData() {
        return (
            <Segment>
                <Header as="strong">Shopify Data {(this.props.shopifyOrder.THIS_SHOPIFY_ORDER_WAS_DELETED) && <Label color="red"><Icon name="warning sign" />This shopify order was deleted</Label>}</Header>
                <ShopifyOrderComponent schemas={this.props.schemas} bigOrder={this.props.bigOrder} shopifyOrder={this.props.shopifyOrder} />
            </Segment>
        );
    }

    renderChecklist() {
        if (this.state.loadingChecklist) {
            return (
                <Segment>
                    <Message icon>
                        <Icon name='circle notched' loading />
                        <Message.Content>
                            Checking order status...
                        </Message.Content>
                    </Message>
                </Segment>
            )
        } else if (this.props.bigOrder.checklistResult) {
            let currentState = this.props.bigOrder.state;
            let nextAction = this.props.bigOrder.nextAction;
            let nextActionMessage = this.props.bigOrder.checklistResult.message;
            let nextActionText = nextAction;

            if (nextAction === "SendScanRequest") {
                nextActionText = "Send scan request email to customer";
            } else if (nextAction === "SendScanRequestReminder") {
                nextActionText = "Send a scan request reminder email to customer";
            }

            let shipmentsList = null;
            if (this.props.shipments.length > 0) {
                shipmentsList = (
                    <>
                        {this.props.shipments.map((shipment, shipmentIndex) => {
                            let color = "green";
                            if (shipment.status === "Cancelled") {
                                color = "red";
                            }
                            return (
                                <div key={`shipment-${shipmentIndex}`} style={{ marginBottom: '0.5em' }}>
                                    <Button icon color={color} href={`/shipper/shipment/${shipment.id}`}>
                                        Shipment {shipment.id}&nbsp;({shipment.status})&nbsp;<Icon name="right arrow" />
                                    </Button>
                                </div>
                            );
                        }
                        )}
                    </>
                );
            }

            let nextActionComponent = null;
            let segmentColor = "green";
            let icon = "warning circle";
            if (nextAction === "SendScanRequest") {
                segmentColor = "red";
                nextActionComponent = <Button color="orange" onClick={this.showNextActionModal.bind(this)} loading={this.state.loading}>OK, {nextActionText}</Button>;
            } else if (nextAction === "SendScanRequestReminder") {
                segmentColor = "purple";
                nextActionComponent = <Button color="purple" onClick={this.showNextActionModal.bind(this)} loading={this.state.loading}>OK, {nextActionText}</Button>;
            } else if (nextAction === "CreateJob") {
                segmentColor = "blue";
                nextActionComponent = <Button color="blue" onClick={this.showCreateJobModal.bind(this)} loading={this.state.loading}>OK, {nextActionText}</Button>;
            } else if (nextAction === "Shipped") {
                segmentColor = "green";
                icon = "checkmark";
                nextActionComponent = shipmentsList;
            } else {
                nextActionComponent = shipmentsList;
            }

            nextActionText = currentState;

            if (this.props.showDetail) {
                return (
                    <Segment color={segmentColor}>
                        <Message icon warning>
                            <Icon name={icon} />
                            <Message.Content>
                                <Message.Header>Status: {nextActionText}</Message.Header>
                                {nextActionMessage}
                            </Message.Content>
                        </Message>
                        {nextActionComponent}
                    </Segment>
                );
            } else if (nextAction !== "Shipped") {
                if (nextActionComponent) {
                    return (
                        <div>
                            <Message icon warning>
                                <Icon name={icon} />
                                <Message.Content>
                                    <Message.Header>Status: {nextActionText}</Message.Header>

                                </Message.Content>
                            </Message>
                            {nextActionComponent}
                        </div>
                    );
                }
            }
        }
        return null;

    }

    renderShipment() {
        if (this.props.bigOrder && this.props.bigOrder.state === "Shipped") {
            return null;
        }

        if (this.state.loading) {
            return (
                <Message icon>
                    <Icon name='circle notched' loading />
                    <Message.Content>
                        Loading shipments...
                    </Message.Content>
                </Message>
            )
        }

        if (this.props.bigOrder.shipmentHold) {
            return (
                <Message icon color="black">
                    <Icon name="pause circle" />
                    <Message.Content>
                        <Message.Header>There is a Hold on this order preventing shipment!</Message.Header>
                        <p>Reason: {this.props.bigOrder.shipmentHold.reason}</p>
                        <p>Notes: {this.props.bigOrder.shipmentHold.notes}</p>
                        <ApiButtonModal loading={this.state.loading} color="green" size="small" icon="play" text="Remove Hold" cancel modalIcon="play" modalButtonText="OK, remove the hold" onConfirm={this.onAdminRemoveShippingHold.bind(this)}>
                            This will remove the hold on the order and allow it to be shipped via BigShipper.
                        </ApiButtonModal>
                    </Message.Content>
                </Message>
            );
        }

        if (this.props.bigOrder.state === "Cancelled") {
            return (
                <Message icon color="red">
                    <Icon name="cancel" />
                    <Message.Content>
                        <Message.Header>This order has been cancelled!</Message.Header>
                    </Message.Content>
                </Message>
            );
        }

        const fulfilledShipments = this.props.shipments.filter(shipment => ["WaitingForPickup", "InTransit", "Shipped", "DeliveryFailed"].includes(shipment.status));

        if (this.state.shipping_summary) {
            // HACK HACK HACK
            //
            // "null" returned as a string. Find out why this is.
            const shipmentGroupIds = Object.keys(this.state.shipping_summary.shipmentGroups).filter(id => id != "null");

            let inventorySummary = shipmentGroupIds.map((shipmentGroupId, i) => {
                let shipment = this.state.shipping_summary.shipmentGroups[shipmentGroupId].shipment;
                let inventorySlots = this.state.shipping_summary.shipmentGroups[shipmentGroupId].inventorySlots;

                let header = <Card.Header>Shipment #{i + 1}</Card.Header>;

                if (inventorySlots) {
                    let availableSlots = inventorySlots.filter(slot => slot.status === "StockAvailable");
                    let inventoryStatusModal = (
                        <ApiButtonModal loading={this.state.loading} color="blue" size="small" icon="list" text="Inventory Availability" cancel modalIcon="list" modalButtonText="OK">
                            {this.state.loading && <Icon name='circle notched' loading />}
                            {(!this.state.loading && inventorySlots) && <Header as="h3">{`${availableSlots.length} out of ${inventorySlots.length} Items In Stock`}</Header>}
                            {(!this.state.loading && inventorySlots) && <BigShipmentInventorySlotsTable bigShipment={{ inventorySlots }} />}
                        </ApiButtonModal>
                    );

                    if (availableSlots.length > 0 && availableSlots.length === inventorySlots.length) {
                        return (
                            <Card color="green">
                                <Card.Content>
                                    {header}
                                    <Card.Meta>Shipment can be completed now:</Card.Meta>
                                </Card.Content>
                                <Card.Content extra>
                                    {inventoryStatusModal}
                                </Card.Content>
                            </Card >
                        );
                    } else {
                        return (
                            <Card color="orange">
                                <Card.Content>
                                    {header}
                                    <Card.Meta>Not enough inventory to ship:</Card.Meta>
                                </Card.Content>
                                <Card.Content extra>
                                    {inventoryStatusModal}
                                </Card.Content>
                            </Card >
                        );
                    }
                } else if (shipment) {
                    let color = "green";
                    return (
                        <Card color="green">
                            <Card.Content>
                                {header}
                                <Card.Meta>This shipment has already been created:</Card.Meta>
                            </Card.Content>
                            <Card.Content extra>
                                <ApiButtonModal loading={this.state.loading} color="green" size="small" icon="list" text="Shipment completed" cancel modalIcon="list" modalButtonText="OK">
                                    {this.state.loading && <Icon name='circle notched' loading />}
                                    {(!this.state.loading) && <Header as="h3">This shipment is {shipment.status}</Header>}
                                    {(!this.state.loading) && <BigShipmentInventorySlotsTable bigShipment={shipment} />}
                                </ApiButtonModal>
                            </Card.Content>
                        </Card >
                    );
                }
            });

            return <Segment><Header as="strong">Shippability</Header><div style={{ padding: '0.5em 0 0 0' }}><Card.Group itemsPerRow={4}>{inventorySummary}</Card.Group></div></Segment>;

        } else {
            return null;
        }
    }

    renderPendingScanRequests() {
        if (this.state.loadingChecklist) {
            return (
                <Segment>
                    <Message icon>
                        <Icon name='circle notched' loading />
                        <Message.Content>
                            Loading scan requests...
                        </Message.Content>
                    </Message>
                </Segment>
            )
        } else if (this.props.scanRequests) {
            const hasScanRequests = this.props.scanRequests.length > 0;
            if (hasScanRequests) {
                return (
                    <Segment>
                        <ScanRequestsTable schemas={this.props.schemas} scanRequests={this.props.scanRequests} />
                    </Segment>
                );
            }
        }

        return null;
    }

    /**
     * Groups consecutive history items with the same message into collapsed groups.
     * Returns an array of groups, where each group has:
     * - items: array of history items in the group
     * - message: the shared message
     * - count: number of items in the group
     */
    groupHistoryItems(history) {
        if (!history || history.length === 0) {
            return [];
        }

        const groups = [];
        let currentGroup = null;

        for (const item of history) {
            if (currentGroup && currentGroup.message === item.message) {
                // Same message as current group, add to it
                currentGroup.items.push(item);
                currentGroup.count++;
            } else {
                // Different message, start a new group
                if (currentGroup) {
                    groups.push(currentGroup);
                }
                currentGroup = {
                    items: [item],
                    message: item.message,
                    count: 1
                };
            }
        }

        // Don't forget the last group
        if (currentGroup) {
            groups.push(currentGroup);
        }

        return groups;
    }

    renderBigOrderStuff() {
        if (!this.props.bigOrder) {
            return null;
        }

        // HACK HACK HACK - hard coding here.
        const looperAccountId = "cc1d57a8-1351-4581-8350-b067dd504791";

        // Group consecutive repeated messages
        const historyGroups = this.groupHistoryItems(this.props.bigOrder.history);

        const bigOrderHistory = historyGroups.flatMap((group, groupIndex) => {
            if (group.count === 1) {
                // Single item, render normally
                const historyItem = group.items[0];
                const accountName = (historyItem.bigscreenAccountId === looperAccountId) ? "factory_looper" : `${historyItem.bigscreenAccountId.substring(0, 8)}`;
                let createdAtDateTime = fromUnixTime(historyItem.createdAt / 1000);
                const createdAt = formatInTimeZone(createdAtDateTime, DEFAULT_TIMEZONE, 'PPPp z');
                return [(
                    <Table.Row key={`historyItem-${groupIndex}-0`}>
                        <Table.Cell width={2}>
                            {createdAt}
                        </Table.Cell>
                        <Table.Cell width={2}>
                            <a href={`/account/${historyItem.bigscreenAccountId}`}>{accountName}</a>
                        </Table.Cell>
                        <Table.Cell>
                            {historyItem.message}
                        </Table.Cell>
                    </Table.Row>
                )];
            } else {
                // Multiple items with same message - show collapsed or expanded
                const isExpanded = this.state.expandedHistoryGroups[groupIndex];
                const firstItem = group.items[0];
                const lastItem = group.items[group.items.length - 1];

                if (isExpanded) {
                    // Show all items in the group with an option to collapse
                    return group.items.map((historyItem, itemIndex) => {
                        const accountName = (historyItem.bigscreenAccountId === looperAccountId) ? "factory_looper" : `${historyItem.bigscreenAccountId.substring(0, 8)}`;
                        let createdAtDateTime = fromUnixTime(historyItem.createdAt / 1000);
                        const createdAt = formatInTimeZone(createdAtDateTime, DEFAULT_TIMEZONE, 'PPPp z');
                        return (
                            <Table.Row
                                key={`historyItem-${groupIndex}-${itemIndex}`}
                                style={{ backgroundColor: '#f8f8f8', cursor: 'pointer' }}
                                onClick={() => this.toggleHistoryGroup(groupIndex)}
                            >
                                <Table.Cell width={2}>
                                    {createdAt}
                                    {itemIndex === 0 && <Label size="tiny" color="blue" style={{ marginLeft: '0.5em' }}>Click to collapse</Label>}
                                </Table.Cell>
                                <Table.Cell width={2}>
                                    <a href={`/account/${historyItem.bigscreenAccountId}`} onClick={e => e.stopPropagation()}>{accountName}</a>
                                </Table.Cell>
                                <Table.Cell>
                                    {historyItem.message}
                                </Table.Cell>
                            </Table.Row>
                        );
                    });
                } else {
                    // Show collapsed row
                    let firstCreatedAtDateTime = fromUnixTime(firstItem.createdAt / 1000);
                    let lastCreatedAtDateTime = fromUnixTime(lastItem.createdAt / 1000);
                    const firstCreatedAt = formatInTimeZone(firstCreatedAtDateTime, DEFAULT_TIMEZONE, 'PPPp z');
                    const lastCreatedAt = formatInTimeZone(lastCreatedAtDateTime, DEFAULT_TIMEZONE, 'PPPp z');
                    const firstAccountName = (firstItem.bigscreenAccountId === looperAccountId) ? "factory_looper" : `${firstItem.bigscreenAccountId.substring(0, 8)}`;

                    return [(
                        <Table.Row
                            key={`historyItem-${groupIndex}-collapsed`}
                            style={{ backgroundColor: '#e0e0e0', cursor: 'pointer' }}
                            onClick={() => this.toggleHistoryGroup(groupIndex)}
                        >
                            <Table.Cell width={2}>
                                {firstCreatedAt}
                                <br />
                                <span style={{ color: '#666', fontSize: '0.9em' }}>→ {lastCreatedAt}</span>
                            </Table.Cell>
                            <Table.Cell width={2}>
                                <a href={`/account/${firstItem.bigscreenAccountId}`} onClick={e => e.stopPropagation()}>{firstAccountName}</a>
                            </Table.Cell>
                            <Table.Cell>
                                {group.message}
                                &nbsp;
                                <Label color="grey" size="small">
                                    <Icon name="repeat" /> {group.count}x repeated
                                </Label>
                            </Table.Cell>
                        </Table.Row>
                    )];
                }
            }
        });

        let createdAtDateTime = fromUnixTime(this.props.bigOrder.createdAt / 1000);
        const createdAt = formatInTimeZone(createdAtDateTime, DEFAULT_TIMEZONE, 'PPPp z');
        const fromNow = formatDistanceToNow(createdAtDateTime, { addSuffix: true });

        return (
            <div>
                <Table compact singleLine loading={this.state.loading}>
                    <Table.Body>
                        <Table.Row>
                            <Table.HeaderCell width={3}>ID</Table.HeaderCell>
                            <Table.Cell><strong>{this.props.bigOrder.id}</strong>&nbsp;<Button size="tiny" onClick={() => { navigator.clipboard.writeText(this.props.bigOrder.id) }}>Copy</Button></Table.Cell>
                        </Table.Row>

                        <Table.Row>
                            <Table.HeaderCell width={3}>Created</Table.HeaderCell>
                            <Table.Cell>{createdAt} ({fromNow})</Table.Cell>
                        </Table.Row>

                        <Table.Row>
                            <Table.HeaderCell width={3}>IPD</Table.HeaderCell>
                            <Table.Cell>{this.props.bigOrder.ipd === -1 ? "Not yet set" : `${this.props.bigOrder.ipd}mm (From ${this.props.bigOrder.ipdSource})`}</Table.Cell>
                        </Table.Row>

                        <Table.Row>
                            <Table.HeaderCell width={3}>Version</Table.HeaderCell>
                            <Table.Cell>{this.props.bigOrder.version}</Table.Cell>
                        </Table.Row>

                        <Table.Row>
                            <Table.HeaderCell width={3}>Priority</Table.HeaderCell>
                            <Table.Cell>{this.props.bigOrder.priority}</Table.Cell>
                        </Table.Row>

                        <Table.Row>
                            <Table.HeaderCell width={3}>Shipping Service Level</Table.HeaderCell>
                            <Table.Cell>{this.props.bigOrder.shippingServiceLevel}</Table.Cell>
                        </Table.Row>
                    </Table.Body>
                </Table>
                <Segment>
                    <Header as="strong">Big Order History</Header>
                    <Table compact celled padded>
                        <Table.Header>
                            <Table.Row>
                                <Table.HeaderCell width={2}>When</Table.HeaderCell>
                                <Table.HeaderCell width={2}>User</Table.HeaderCell>
                                <Table.HeaderCell fluid="true">Message</Table.HeaderCell>
                            </Table.Row>
                        </Table.Header>
                        <Table.Body>
                            {bigOrderHistory}
                        </Table.Body>
                    </Table>
                </Segment>
            </div>
        )
    }


    renderLineItemsForShipmentGroup(shipmentGroupId, lineItems, color="blue") {
        return lineItems.map(lineItem => {
            if (lineItem.type === this.props.schemas.BigProductTypes.Other) {
                return null;
            }

            if (lineItem.shipmentGroupId !== shipmentGroupId) {
                return null;
            }

            let title = lineItem.type;
            let variantTitle = "Unknown Variant";
            let sku = lineItem.shopifySku;
            let quantity = 1;
            let imageSrc = `/images/${lineItem.type}.png`;

            const shopifyLineItem = lineItem.shopifyOrderLineItemSnapshot;
            if (shopifyLineItem && shopifyLineItem.product_id && shopifyLineItem.variant_id) {
                quantity = shopifyLineItem.quantity;

                const product = this.props.products.find(product => product.id === shopifyLineItem.product_id);
                if (product) {
                    title = product.title;
                    imageSrc = product.image.src;
                }

                const variant = product.variants.find(variant => variant.id === shopifyLineItem.variant_id);
                if (variant) {
                    variantTitle = variant.title;

                    // Get the image for the variant from the product - need to look up the images array on the product
                    const variantImage = product.images.find(image => image.id === variant.image_id);
                    if (variantImage) {
                        imageSrc = variantImage.src;
                    }
                }
            }

            const lineItemData = <div>{quantity}x <Label>{title} (SKU: {sku})</Label></div>;

            if (lineItem.type === this.props.schemas.BigProductTypes.PrescriptionLenses) {
                return (
                    <Segment clearing color={color}>
                        <Header as="h3">{title}</Header>
                        <Image size='tiny' floated='left' src={imageSrc} />
                        {lineItemData}
                        <p>OS Left: <strong>{lineItem.OSLeft}</strong></p>
                        <p>OD Right: <strong>{lineItem.ODRight}</strong></p>
                    </Segment>
                );
            }

            if (lineItem.type === this.props.schemas.BigProductTypes.CustomCushion
                || lineItem.type === this.props.schemas.BigProductTypes.BeyondCushionV1
                || lineItem.type === this.props.schemas.BigProductTypes.ReplacementBeyondCushionV1) {
                const jobInfo = (_.isEmpty(lineItem.currentJobId))
                    ? <Label color="orange">NO JOB - WAITING FOR CUSTOMER SCAN</Label>
                    : <Button inverted color="blue" size="tiny" href={`/fabricator/job/${lineItem.currentJobId}`}><Icon name='cog' />Job #{lineItem.currentJobId}</Button>;

                return (
                    <Segment clearing color={color}>
                        <Header as="h3">{title}</Header>
                        <Image size='tiny' floated='left' src={imageSrc} />

                        {lineItemData}
                        <div>Current Job: {jobInfo}</div>
                    </Segment>
                )
            }

            if (lineItem.type === this.props.schemas.BigProductTypes.UniversalLightFitSeal) {
                title = "Universal Lightfit Seal";
                variantTitle = "AKA BS1U";
            }

            return (
                <Segment clearing color={color}>
                    <Header as="h3">{title} ({variantTitle})</Header>
                    <Image size='tiny' floated='left' src={imageSrc} />
                    {lineItemData}
                </Segment>
            );
        });
    }


    renderLineItemsV3() {
        if (!this.props.schemas) {
            return null;
        }

        if (!this.props.products) {
            return null;
        }

        if (!this.state.shipping_summary) {
            return null;
        }

        let unfulfilledLineItems = [];
        let fulfilledLineItems = [];
        let refundedLineItems = [];
        let lineItemSummary = this.state.shipping_summary.lineItemSummary;
        let unfulfilledTitle = "Pending Shipments";
        if (lineItemSummary) {
            fulfilledLineItems = lineItemSummary.lineItems.filter(lineItem => lineItemSummary.fulfilledLineItemIds.includes(lineItem.shopifyOrderLineItemId));
            unfulfilledLineItems = lineItemSummary.lineItems.filter(lineItem => lineItemSummary.unfulfilledLineItemIds.includes(lineItem.shopifyOrderLineItemId));
            refundedLineItems = lineItemSummary.lineItems.filter(lineItem => lineItemSummary.refundedLineItemIds.includes(lineItem.shopifyOrderLineItemId));
        } else {
            unfulfilledLineItems = this.props.bigOrder.currentLineItems;
            unfulfilledTitle = "Shipments";
        }

        let components = [];

        if (unfulfilledLineItems.length > 0) {
            const shipmentGroupIds = _.uniq(unfulfilledLineItems.map((lineItem) => lineItem.shipmentGroupId));
            components.push((
                <Segment>
                    <Header as="strong">{unfulfilledTitle} ({shipmentGroupIds.length})</Header>
                    &nbsp;<Button loading={this.state.loading} onClick={this.onSynchronizeBigOrder.bind(this)} color="blue" size="small"><Icon name='recycle' />Synchronize</Button>
                    {shipmentGroupIds.map((shipmentGroupId, shipmentGroupIndex) => {
                        const lineItems = this.renderLineItemsForShipmentGroup(shipmentGroupId, unfulfilledLineItems, "white");
                        if (_.isEmpty(lineItems)) {
                            return null;
                        }

                        return (
                            <div key={`shipmentGroup${shipmentGroupIndex}`}>
                                <br /><Header as="strong">Shipment {shipmentGroupIndex + 1}</Header>
                                &nbsp;<Button loading={this.state.loading} onClick={this.onCreateShipment.bind(this, shipmentGroupId)} color="green" size="small"><Icon name='shipping fast' />Create Shipment</Button>
                                {lineItems}
                            </div>
                        );
                    })}
                </Segment>
            ));
        }

        if (this.state.shipments && this.state.shipments.length > 0 && fulfilledLineItems.length > 0) {
            const shipmentGroupIds = _.uniq(this.state.shipments.filter(shipment => shipment.status != "Cancelled").map((shipment) => shipment.shipmentGroupId));
            components.push((
                <Segment>
                    <Header as="strong">Completed Shipments ({shipmentGroupIds.length})</Header>
                    {shipmentGroupIds.map((shipmentGroupId, shipmentGroupIndex) => {
                        
                        const lineItems = this.renderLineItemsForShipmentGroup(shipmentGroupId, fulfilledLineItems, "blue");
                        if (_.isEmpty(lineItems)) {
                            return null;
                        }

                        // Find the shipment that corresponds to this shipmentGroupId
                        const shipment = this.state.shipments.find(s => s.shipmentGroupId === shipmentGroupId && (s.status === "Shipped" || s.status === "WaitingForPickup"));

                        // Only show return label button for Shipped or WaitingForPickup shipments
                        let returnLabelButton = null;
                        if (shipment) {
                            returnLabelButton = (
                                <span style={{ marginLeft: '0.5em' }}>
                                    {this.renderReturnLabelModal(shipment.id)}
                                </span>
                            );
                        }

                        return (
                            <div key={`shipmentGroup${shipmentGroupIndex}`}>
                                <br /><Header as="strong">Shipment {shipmentGroupIndex + 1}</Header>
                                {returnLabelButton}
                                {lineItems}
                            </div>
                        );
                    })}
                </Segment>
            ));
        }

        if (refundedLineItems.length > 0) {
            components.push((
                <Segment color="red">
                    <Header as="strong">({refundedLineItems.length} Refunded or Cancelled items hidden)</Header>
                </Segment>
            ));
        }

        return <>{components.map((component, index) => <React.Fragment key={index}>{component}</React.Fragment>)}</>;
    }


    renderNextActionModal() {
        return (
            <Modal dimmer="inverted" closeOnEscape={true} closeOnDimmerClick={true} closeIcon
                onClose={this.closeNextActionModal.bind(this)}
                open={this.state.showNextActionModal}>
                <Header icon='user' content='Send a scan request' />
                <Modal.Content>
                    Send a scan request email to this user? This action may take several seconds.
                </Modal.Content>
                <Modal.Actions>
                    <Button color='orange' loading={this.state.loading} onClick={this.onNextAction.bind(this)}>
                        <Icon name='checkmark' />Yes, Send Scan Request
                    </Button>
                </Modal.Actions>
            </Modal>
        )
    }

    renderCreateJobModal() {
        return (
            <Modal dimmer="inverted" closeOnEscape={true} closeOnDimmerClick={true} closeIcon
                onClose={this.closeCreateJobModal.bind(this)}
                open={this.state.showCreateJobModal}>
                <Header icon='cog' content='Create a job' />
                <Modal.Content>
                    This step will create a job for this order. This action may take several seconds while the job is created and the scan verified.
                    <p> </p>
                    <p>Set an optional priority for the job</p>
                    <Form.Input size="medium" name="priority" value={this.state.priority} onChange={this.onChange} />
                </Modal.Content>
                <Modal.Actions>
                    <Button color='blue' loading={this.state.loading} onClick={this.onCreateJob.bind(this)}>
                        <Icon name='checkmark' />Create the job
                    </Button>
                </Modal.Actions>
            </Modal>
        )
    }

    render() {
        if (!this.props.bigOrder) {
            return null;
        }

        if (this.props.asTableRow) {
            let urlOrderId = this.props.bigOrder.id;
            if (this.props.bigOrder.shopifyOrderName) {
                urlOrderId = this.props.bigOrder.shopifyOrderName;
            }

            return (
                <ClickableTableRow key={this.props.bigOrder.id} allowClicks={this.props.allowClicks} href={`/shop/order/${urlOrderId}`}>
                    <BigOrderTableCells
                        bigOrder={this.props.bigOrder}
                        shopifyOrder={this.props.shopifyOrder}
                        shipmentGroupId={this.props.shipmentGroupId}
                        loadingChecklist={this.state.loadingChecklist}
                    />
                </ClickableTableRow>
            );
        } else {
            if (!this.props.shopifyOrder) {
                return null;
            }

            return (
                <div>
                    {this.renderNextActionModal()}

                    {this.renderCreateJobModal()}

                    {this.renderBanners()}

                    {this.renderTitle()}

                    {this.renderShipment()}

                    {this.renderChecklist()}

                    {this.renderBigOrderStuff()}

                    {this.renderPendingScanRequests()}

                    {this.renderShopifyData()}
                    {(this.props.showDetail) && this.renderLineItemsV3()}
                </div>
            );
        }
    }
}
