import {
    Alert,
    Button,
    DatePicker,
    HelpTooltip,
} from '@theorchard/suite-components';
import { useAppConfig } from '@theorchard/suite-frontend';
import dayjs from 'dayjs';
import { isEmpty } from 'lodash';
import React, { useRef, useState } from 'react';
import ReleaseScheduleTable from 'src/components/releaseScheduleTable';
import { calcProcessAtDisplayDate } from 'src/components/timedReleaseScheduleModal/timed-release-schedule-modal';
import PreorderDropdown from './preorderDropdown/preorder-dropdown';
import type { FC } from 'react';
import type { PreorderType, Product, ReleaseType } from 'src/types';

const releaseScheduleDocLink =
    'https://docs.google.com/document/d/1hQAJ3hDmFPBlyDcb1uE09jVIQE_yTLGbedO3k1ojUqE/edit?usp=sharing';

interface DateRowProps {
    value?: Date;
    editable: boolean;
    nullable?: boolean;
    field: 'salesStartDate' | 'releaseDate';
    info?: string;
    warning?: string;
    error?: string;
    onChange: (value?: Date | null) => void;
}

const DateRow: FC<DateRowProps> = ({
    value,
    editable,
    nullable = false,
    field,
    info,
    warning,
    error,
    onChange,
}) => (
    <div className="date-row">
        <div className="field-name">
            {$t(`releaseScheduler.productDetails.${field}`)}:
        </div>
        <div className="detail row-input">
            {editable ? (
                <DatePicker
                    isClearable={false}
                    testId={field}
                    selectedValue={dayjs(value).format('YYYY-MM-DD')}
                    onChange={value =>
                        nullable && !value
                            ? onChange(null)
                            : onChange(dayjs(value).toDate())
                    }
                />
            ) : value ? (
                <div className="display-value">
                    {dayjs(value).format('YYYY-MM-DD')}
                </div>
            ) : (
                '--'
            )}
            {info && (
                <Alert
                    testId={`${field}-info`}
                    className="ProductDetails-info"
                    variant="information"
                    text={info}
                />
            )}
            {warning && (
                <Alert
                    testId={`${field}-warning`}
                    className="ProductDetails-warning"
                    variant="warn"
                    text={warning}
                />
            )}
            {error && (
                <Alert
                    testId={`${field}-error`}
                    className="ProductDetails-error"
                    variant="error"
                    text={error}
                />
            )}
        </div>
    </div>
);

const doesUtcDateSpanTwoDays = (datetime: string) => {
    const earliestDate = dayjs.utc(
        dayjs.utc(datetime).utcOffset(-12).format('YYYY-MM-DD')
    );
    const providedDate = dayjs.utc(dayjs.utc(datetime).format('YYYY-MM-DD'));
    return earliestDate.isBefore(providedDate);
};

export interface ProductDetailsProps {
    product: Product;
    preorderType?: PreorderType;
    editable: boolean;
    onModalOpen: (releaseType: ReleaseType) => void;
    onProductChange: (product: Product) => void;
    setPreorderType: (type: PreorderType) => void;
    errors: { preorderDate: boolean };
}

const ProductDetails: FC<ProductDetailsProps> = ({
    product,
    preorderType,
    editable,
    onModalOpen,
    onProductChange,
    setPreorderType,
    errors,
}) => {
    const { userFeatureFlags } = useAppConfig();
    const hasAutomaticTimedReleasePadding =
        userFeatureFlags?.['ccm_timed_releases_workstation'];

    const hasPhysicalDateChangeInfoMessage =
        userFeatureFlags?.['ccm_physical_supplychaininfo_oa'];

    const { staggered, timed, unsupportedTimed } = product.releaseSchedule;
    const timedTooltipContainer = useRef<HTMLDivElement>(null);
    const staggeredTooltipContainer = useRef<HTMLDivElement>(null);
    const [showSalesStartDateWarning, setShowSalesStartDateWarning] =
        useState(false);

    const existingSaleDateTime = isEmpty(unsupportedTimed)
        ? undefined
        : unsupportedTimed[0].saleDateTime;

    const scheduledUpdateProcessed =
        isEmpty(existingSaleDateTime) || !product.saleStartDate
            ? undefined
            : dayjs.utc(existingSaleDateTime).isBefore(dayjs.utc()) &&
              dayjs
                  .utc(product.saleStartDate)
                  .isSame(
                      dayjs.utc(existingSaleDateTime).subtract(1, 'day'),
                      'date'
                  );

    const existingTimeOffset = isEmpty(unsupportedTimed)
        ? undefined
        : unsupportedTimed[0].timeOffset;

    const salesStartDateInfoMessages: string[] = [];

    if (
        scheduledUpdateProcessed &&
        existingSaleDateTime &&
        doesUtcDateSpanTwoDays(existingSaleDateTime)
    ) {
        salesStartDateInfoMessages.push(
            $t('releaseScheduler.productDetails.earliestSalesStartDateInfo', {
                salesStartDate: dayjs
                    .utc(existingSaleDateTime)
                    .format('YYYY-MM-DD'),
            })
        );
    }

    if (!isEmpty(timed) && editable && hasAutomaticTimedReleasePadding) {
        salesStartDateInfoMessages.push(
            $t(
                'releaseScheduler.productDetails.timedReleaseAutomaticPaddingInfo'
            )
        );
    }

    const showPhysicalDateChangeInfoMessage =
        hasPhysicalDateChangeInfoMessage &&
        showSalesStartDateWarning &&
        product.contextType === 'physical';

    return (
        <div className="ProductDetails">
            <div className="ProductDetails-date-rows">
                <DateRow
                    value={product.saleStartDate}
                    field="salesStartDate"
                    editable={editable}
                    onChange={saleStartDate => {
                        setShowSalesStartDateWarning(true);

                        saleStartDate &&
                            onProductChange({ ...product, saleStartDate });
                    }}
                    info={
                        [
                            ...(salesStartDateInfoMessages.length > 0
                                ? [salesStartDateInfoMessages.join(' ')]
                                : []),
                            ...(showPhysicalDateChangeInfoMessage
                                ? [
                                      $t(
                                          'releaseScheduler.productDetails.saleStartDateInfoForPhysical'
                                      ),
                                  ]
                                : []),
                        ].join(' ') || undefined
                    }
                    warning={
                        !scheduledUpdateProcessed &&
                        !isEmpty(timed) &&
                        editable &&
                        !hasAutomaticTimedReleasePadding
                            ? $t(
                                  'releaseScheduler.productDetails.salesStartDateWarning',
                                  { numberDays: 2 }
                              )
                            : undefined
                    }
                />
                <DateRow
                    value={product.releaseDate}
                    field="releaseDate"
                    editable={editable}
                    onChange={releaseDate =>
                        releaseDate &&
                        onProductChange({ ...product, releaseDate })
                    }
                />
                <PreorderDropdown
                    value={product.preorderDate}
                    type={preorderType}
                    setType={setPreorderType}
                    approvalDate={product.ingestionCompleted}
                    editable={editable}
                    onChange={preorderDate => {
                        let updatedProduct = { ...product, preorderDate };
                        if (
                            product.preorderDate !== null &&
                            preorderDate === null
                        )
                            updatedProduct = {
                                ...updatedProduct,
                                previewable: null,
                            };
                        else if (
                            product.preorderDate === null &&
                            preorderDate !== null
                        )
                            updatedProduct = {
                                ...updatedProduct,
                                previewable: 'no',
                            };
                        onProductChange(updatedProduct);
                    }}
                    error={
                        errors.preorderDate && editable
                            ? preorderType === 'specific-date' &&
                              !product.preorderDate
                                ? $t(
                                      'releaseScheduler.productDetails.preorderSpecificDateError'
                                  )
                                : $t(
                                      'releaseScheduler.productDetails.preorderAfterSalesDateError'
                                  )
                            : undefined
                    }
                />
            </div>
            {product.contextType === 'digital' && (
                <>
                    <div
                        className="ProductDetails-schedule-table"
                        data-testid="release-schedule-table"
                    >
                        <div className="ProductDetails-table-header">
                            <div
                                className="ProductDetails-table-title"
                                ref={timedTooltipContainer}
                            >
                                {$t(
                                    'releaseScheduler.productDetails.timedReleases'
                                )}
                                <HelpTooltip
                                    id="timed-release-help-tooltip"
                                    testId="timed-release-help-tooltip"
                                    container={timedTooltipContainer}
                                    message={
                                        <>
                                            {$t(
                                                'releaseScheduler.productDetails.timedReleaseTooltip'
                                            )}
                                            <br />
                                            <a
                                                href={releaseScheduleDocLink}
                                                target="_blank"
                                                rel="noreferrer"
                                            >
                                                {$t(
                                                    'releaseScheduler.productDetails.clickForDocumentation'
                                                )}
                                            </a>
                                        </>
                                    }
                                />
                            </div>
                            {editable &&
                                (!isEmpty(timed) ||
                                    !isEmpty(unsupportedTimed)) && (
                                    <Button
                                        className="ProductDetails-modal-link"
                                        data-testid="manage-timed-releases"
                                        variant="link"
                                        onClick={() => onModalOpen('timed')}
                                    >
                                        {$t(
                                            'releaseScheduler.productDetails.manageTimedReleases'
                                        )}
                                    </Button>
                                )}
                        </div>
                        <div className="detail">
                            {(!isEmpty(timed) || isEmpty(unsupportedTimed)) && (
                                <ReleaseScheduleTable
                                    testId="timed-supported-table"
                                    className="ProductDetails-table"
                                    releaseSchedule={timed}
                                    editable={false}
                                    totalServicesPrompt={$t(
                                        'releaseScheduler.productDetails.supportedServicesPrompt'
                                    )}
                                    manageButton={
                                        editable && (
                                            <Button
                                                className="ProductDetails-modal-link"
                                                data-testid="manage-timed-releases"
                                                variant="link"
                                                onClick={() =>
                                                    onModalOpen('timed')
                                                }
                                            >
                                                {$t(
                                                    'releaseScheduler.productDetails.manageTimedReleases'
                                                )}
                                            </Button>
                                        )
                                    }
                                />
                            )}
                            {!isEmpty(unsupportedTimed) && (
                                <>
                                    {existingSaleDateTime &&
                                        existingTimeOffset && (
                                            <Alert
                                                className="ProductDetails-timed-unsupported-alert"
                                                testId="timed-unsupported-alert"
                                                text={$t(
                                                    'releaseScheduler.timedReleaseScheduleModal.nonTimedReleaseSupport',
                                                    {
                                                        dateString:
                                                            calcProcessAtDisplayDate(
                                                                existingSaleDateTime,
                                                                existingTimeOffset
                                                            ),
                                                    }
                                                )}
                                                variant="information"
                                            />
                                        )}
                                    <ReleaseScheduleTable
                                        testId="timed-unsupported-table"
                                        className="ProductDetails-table"
                                        releaseSchedule={unsupportedTimed}
                                        editable={false}
                                        totalServicesPrompt={$t(
                                            'releaseScheduler.productDetails.unsupportedServicesPrompt'
                                        )}
                                    />
                                </>
                            )}
                        </div>
                    </div>
                    <div
                        className="ProductDetails-schedule-table"
                        data-testid="release-schedule-table"
                    >
                        <div className="ProductDetails-table-header">
                            <div
                                className="ProductDetails-table-title"
                                ref={staggeredTooltipContainer}
                            >
                                {$t(
                                    'releaseScheduler.productDetails.staggeredReleases'
                                )}
                                <HelpTooltip
                                    id="staggered-release-help-tooltip"
                                    testId="staggered-release-help-tooltip"
                                    container={staggeredTooltipContainer}
                                    message={
                                        <>
                                            {$t(
                                                'releaseScheduler.productDetails.staggeredReleaseTooltip'
                                            )}
                                            <br />
                                            <a
                                                href={releaseScheduleDocLink}
                                                target="_blank"
                                                rel="noreferrer"
                                            >
                                                {$t(
                                                    'releaseScheduler.productDetails.clickForDocumentation'
                                                )}
                                            </a>
                                        </>
                                    }
                                />
                            </div>
                            {editable && !isEmpty(staggered) && (
                                <Button
                                    className="ProductDetails-modal-link"
                                    data-testid="manage-staggered-releases"
                                    variant="link"
                                    onClick={() => onModalOpen('staggered')}
                                >
                                    {$t(
                                        'releaseScheduler.productDetails.manageStaggeredReleases'
                                    )}
                                </Button>
                            )}
                        </div>
                        <div className="detail">
                            <ReleaseScheduleTable
                                className="ProductDetails-table"
                                releaseSchedule={staggered}
                                editable={false}
                                manageButton={
                                    editable && (
                                        <Button
                                            className="ProductDetails-modal-link"
                                            data-testid="manage-staggered-releases"
                                            variant="link"
                                            onClick={() =>
                                                onModalOpen('staggered')
                                            }
                                        >
                                            {$t(
                                                'releaseScheduler.productDetails.manageStaggeredReleases'
                                            )}
                                        </Button>
                                    )
                                }
                            />
                        </div>
                    </div>
                </>
            )}
        </div>
    );
};

export default ProductDetails;
