/*
 * Copyright (C) Contributors to the Suwayomi project
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

import Stack from '@mui/material/Stack';
import { MigrationProgressBar } from '@/features/migration/components/MigrationProgressBar.tsx';
import { useLingui } from '@lingui/react/macro';
import { useAppTitleAndAction } from '@/features/navigation-bar/hooks/useAppTitleAndAction.ts';
import { MigrationManager } from '@/features/migration/MigrationManager.ts';
import { MigrationEntryStatus, MigrationPhase } from '@/features/migration/Migration.types.ts';
import { useMemo } from 'react';
import { DEFAULT_FULL_FAB_HEIGHT } from '@/base/components/buttons/StyledFab.tsx';
import { MigrationContinueButton } from '@/features/migration/components/MigrationContinueButton.tsx';
import { plural } from '@lingui/core/macro';
import { MigrationEntryGroup } from '@/features/migration/components/MIgrationEntryGroup.tsx';
import { MigrationEntries } from '@/features/migration/MigrationEntries.ts';

export const MigrationExecute = () => {
    const { t } = useLingui();

    const phase = MigrationManager.usePhase();
    const entries = MigrationManager.useEntries();
    const progress = MigrationManager.useMigrationProgress();

    useAppTitleAndAction(
        (() => {
            if (MigrationManager.getState().isAborted) {
                return t`Aborted`;
            }

            if (MigrationManager.isPhaseComplete()) {
                return t`Migration complete`;
            }

            return t`Migrating`;
        })(),
        undefined,
        [MigrationManager.isPhaseComplete()],
    );

    const isMigrating = phase === MigrationPhase.MIGRATING;

    const entryList = useMemo(() => Object.values(entries), [entries]);
    const migratingEntries = useMemo(
        () =>
            MigrationEntries.getActiveEntriesSorted(
                entryList,
                MigrationEntryStatus.MIGRATING,
                MigrationEntryStatus.MIGRATION_PENDING,
                MigrationEntryStatus.MIGRATING,
            ),
        [entryList],
    );
    const migratedEntries = useMemo(
        () => MigrationEntries.getHaveStatusSorted(entryList, MigrationEntryStatus.MIGRATION_COMPLETE),
        [entryList],
    );
    const failedEntries = useMemo(
        () => MigrationEntries.getHaveStatusSorted(entryList, MigrationEntryStatus.MIGRATION_FAILED),
        [entryList],
    );
    const abortedEntries = useMemo(
        () => MigrationEntries.getHaveStatusSorted(entryList, MigrationEntryStatus.MIGRATION_ABORTED),
        [entryList],
    );
    const excludedEntries = useMemo(() => MigrationEntries.getExcluded(entryList), [entryList]);
    const noMatchEntries = useMemo(
        () => MigrationEntries.getHaveStatusSorted(entryList, MigrationEntryStatus.SEARCH_NO_MATCH),
        [entryList],
    );
    const outdatedEntries = useMemo(
        () => MigrationEntries.getHaveStatusSorted(entryList, MigrationEntryStatus.SEARCH_OUTDATED),
        [entryList],
    );

    return (
        <>
            <MigrationProgressBar
                {...progress}
                label={t`${progress.completed} / ${progress.total}${progress.failed > 0 ? ` (${progress.failed} failed)` : ''}`}
            />

            <Stack
                direction="row"
                sx={{ p: 2, pb: DEFAULT_FULL_FAB_HEIGHT, gap: 4, flexWrap: 'wrap', justifyContent: 'center' }}
            >
                <MigrationEntryGroup
                    status={MigrationEntryStatus.MIGRATING}
                    title={plural(migratingEntries.length, {
                        one: '1 migrating entry',
                        other: '# migrating entries',
                    })}
                    entries={migratingEntries}
                    isMigrating={isMigrating}
                    isAborted={MigrationManager.getState().isAborted}
                    color="info"
                />
                <MigrationEntryGroup
                    status={MigrationEntryStatus.MIGRATION_FAILED}
                    title={plural(failedEntries.length, {
                        one: '1 failed entry',
                        other: '# failed entries',
                    })}
                    entries={failedEntries}
                    isMigrating={isMigrating}
                    isAborted={MigrationManager.getState().isAborted}
                    color="error"
                />
                <MigrationEntryGroup
                    status={MigrationEntryStatus.MIGRATION_ABORTED}
                    title={plural(abortedEntries.length, {
                        one: '1 aborted entry',
                        other: '# aborted entries',
                    })}
                    entries={abortedEntries}
                    color="warning"
                    isMigrating={isMigrating}
                    isAborted={MigrationManager.getState().isAborted}
                />
                <MigrationEntryGroup
                    status={MigrationEntryStatus.SEARCH_NO_MATCH}
                    title={plural(noMatchEntries.length, {
                        one: '1 entry with no match',
                        other: '# entries with no match',
                    })}
                    entries={noMatchEntries}
                    color="warning"
                    isMigrating={isMigrating}
                    isAborted={MigrationManager.getState().isAborted}
                />
                <MigrationEntryGroup
                    status={MigrationEntryStatus.SEARCH_OUTDATED}
                    title={plural(outdatedEntries.length, {
                        one: '1 entry with only outdated matches',
                        other: '# entries with only outdated matches',
                    })}
                    entries={outdatedEntries}
                    isAborted={MigrationManager.getState().isAborted}
                    color="warning"
                />
                <MigrationEntryGroup
                    status={MigrationEntryStatus.EXCLUDED}
                    title={plural(excludedEntries.length, {
                        one: '1 excluded entry',
                        other: '# excluded entries',
                    })}
                    entries={excludedEntries}
                    color="info"
                    isMigrating={isMigrating}
                    isAborted={MigrationManager.getState().isAborted}
                />
                <MigrationEntryGroup
                    status={MigrationEntryStatus.MIGRATION_COMPLETE}
                    title={plural(migratedEntries.length, {
                        one: '1 migrated entry',
                        other: '# migrated entries',
                    })}
                    entries={migratedEntries}
                    color="success"
                    isMigrating={isMigrating}
                    isAborted={MigrationManager.getState().isAborted}
                />
            </Stack>

            <MigrationContinueButton
                title={MigrationManager.isPhaseComplete() ? t`Done` : t`Abort`}
                onClick={() =>
                    MigrationManager.isPhaseComplete() ? MigrationManager.reset() : MigrationManager.stop()
                }
            />
        </>
    );
};
