import React, { useMemo, useRef, useState } from 'react'

import {
  getFlatResources,
  getGroupedMissingTranslations,
  getMissingTranslationCount,
  type MissingTranslation,
  type Resources,
  SUPPORTED_LANGUAGES,
  type SupportedLanguageKeys,
} from './TranslationTools.models'
import { PageHeader } from '../PageHeader/PageHeader'
import Button from '../Button/Button'
import { capitalize } from '../../services/HelperServiceTyped'
import {
  type ConfigItemType,
  type GroupColorType,
} from '../TableComponents/StandardTable.models'
import EmptyState from '../EmptyState/EmptyState'
import StandardTable from '../TableComponents/StandardTable'
import Switch from '../Switch/Switch'
import { toast } from '../Toast/Toast'
import styles from './_translation-tools.module.scss'
import ScrollingContainer from '../ScrollingContainer/ScrollingContainer'
import { c } from '../../translations/LibraryTranslationService'

const TranslationTools = ({
  languagesToCheck,
  resources,
  hideReturnToAppButton,
}: {
  languagesToCheck: SupportedLanguageKeys[]
  resources: Resources
  hideReturnToAppButton?: boolean
}): React.JSX.Element => {
  const [isAIPrompt, setIsAIPrompt] = useState(false)
  const groupedMissingTranslations = useMemo(
    () => getGroupedMissingTranslations({ resources, languagesToCheck }),
    [languagesToCheck, resources],
  )
  const totalMissingTranslations = useMemo(
    () => getMissingTranslationCount(groupedMissingTranslations),
    [groupedMissingTranslations],
  )
  const flatResources = useMemo(() => getFlatResources(resources), [resources])

  interface Translation {
    englishValue: string
    language: string
    key: string
  }

  interface Module {
    [moduleName: string]: Translation[]
  }

  interface LanguageData {
    [languageCode: string]: Module
  }

  function getTotalCounts(data: LanguageData): {
    [languageCode: string]: number
  } {
    const counts: { [languageCode: string]: number } = {}

    for (const languageCode in data) {
      if (Object.prototype.hasOwnProperty.call(data, languageCode)) {
        let totalCount = 0
        const modules = data[languageCode]

        for (const moduleName in modules) {
          if (Object.prototype.hasOwnProperty.call(modules, moduleName)) {
            totalCount += modules[moduleName].length
          }
        }

        counts[languageCode] = totalCount
      }
    }

    return counts
  }

  const totalCounts = getTotalCounts(groupedMissingTranslations)

  const TranslationCard = ({
    language,
    modules,
  }: {
    language: SupportedLanguageKeys
    modules: Record<string, MissingTranslation[]>
  }): React.JSX.Element => {
    const textRef = useRef<HTMLDivElement>(null)

    const copyToClipboard = () => {
      if (textRef.current) {
        navigator.clipboard.writeText(textRef.current.innerText).then(
          () => {
            toast({ message: c('textCopiedToClipboard'), type: 'success' })
          },
          (err) => {
            toast({
              message: c('failedToCopyText', {
                error: err,
              }),
              type: 'error',
            })
          },
        )
      }
    }

    type Modules = {
      [key: string]: Translation[]
    }

    type TransformedTranslation = Translation & { module: string }

    function transformData(data: Modules): TransformedTranslation[] {
      const result: TransformedTranslation[] = []

      Object.keys(data).forEach((moduleKey) => {
        const translations = data[moduleKey]
        const transformedTranslations = translations.map((translation) => ({
          module: moduleKey,
          ...translation,
        }))
        result.push(...transformedTranslations)
      })

      return result
    }

    const data = transformData(modules)

    const tableConfig: ConfigItemType<
      TransformedTranslation,
      Record<string, unknown>
    >[] = [
      {
        label: 'Translation Key',
        name: 'key',
        cell: {
          children: (d): React.JSX.Element => {
            return <div>{d.key}</div>
          },
        },
        noSort: true,
      },
      {
        label: 'English Value',
        name: 'englishValue',
        cell: {
          children: (d): React.JSX.Element => {
            return <div>{d.englishValue}</div>
          },
        },
        noSort: true,
      },
    ]

    const groups = Object.keys(modules).map((module) => ({
      groupHeader: capitalize(module),
      type: 'gray' as GroupColorType,
      check: (translation: TransformedTranslation) =>
        translation.module === module,
    }))

    return (
      <div key={language} className={styles.languageContainer}>
        <div
          className={`${styles.languageHeader} ${isAIPrompt ? styles.blueBg : ''}`}
        >
          <div
            className={`${styles.languageName} ${isAIPrompt ? styles.blueColor : ''}`}
          >
            {SUPPORTED_LANGUAGES[language].language} ({language}) -{' '}
            {totalCounts[language]}
          </div>
          <Button
            onClick={copyToClipboard}
            icon='clipboard'
            disabled={!isAIPrompt}
            tooltip={{
              tooltipContent: c('copyAiPromptToClipboard', {
                language: SUPPORTED_LANGUAGES[language].language,
              }),
            }}
          />
        </div>
        <div className={styles.languageBody} ref={textRef}>
          {!isAIPrompt ? (
            <StandardTable
              data={data}
              config={tableConfig}
              dataKey='key'
              hasData
              loading={false}
              tableId='translation-table'
              noDataFields={{
                primaryText: c('allCaughtUp'),
                secondaryText: c('noMoreTranslations', {
                  language: SUPPORTED_LANGUAGES[language].language,
                }),
              }}
              successStatus
              customHeight='500px'
              customWidth='auto'
              noMobileView
              groups={groups}
              showGroups
              noSort
            />
          ) : Object.entries(modules).length > 0 ? (
            <ScrollingContainer height='500px'>
              {isAIPrompt ? (
                <div>
                  <div>
                    Translate all of these values to{' '}
                    {SUPPORTED_LANGUAGES[language].language}. Keep the keys the
                    same.
                  </div>
                  <div>```</div>
                </div>
              ) : null}
              {Object.entries(modules).map(
                ([moduleKey, translations], index) => (
                  <div key={moduleKey}>
                    {!isAIPrompt && (
                      <div className={styles.moduleKey}>{moduleKey}</div>
                    )}
                    {translations.map((translation, index) => (
                      <div key={index}>
                        {`"${translation?.key}": "${translation?.englishValue}",`}
                      </div>
                    ))}
                    {index !== Object.entries(modules).length - 1 && <br />}
                  </div>
                ),
              )}
              {isAIPrompt ? <>```</> : null}
            </ScrollingContainer>
          ) : (
            <EmptyState
              primaryText={c('allCaughtUp')}
              secondaryText={c('noMoreTranslations', {
                language: SUPPORTED_LANGUAGES[language].language,
              })}
            />
          )}
        </div>
      </div>
    )
  }

  return (
    <div className={styles.body}>
      <PageHeader
        header={{
          name: 'Total Missing Translations',
          value: totalMissingTranslations,
        }}
        download={{
          csvDownloadOptions: [
            {
              linkName: 'Download Translations',
              csvName: 'translation_resources',
              csvData: flatResources,
              callout: (element) => (element as HTMLDivElement)?.click(),
            },
          ],
          initialDisplay: true,
          show: true,
        }}
        rightSectionChildren={
          <div className={styles.rightSection}>
            <Switch
              callout={() => setIsAIPrompt(!isAIPrompt)}
              checked={isAIPrompt}
              formLabelProps={{
                label: 'AI Prompts',
              }}
              disabled={totalMissingTranslations === 0}
            />
            {!hideReturnToAppButton ? (
              <>
                <PageHeader.HeaderDivider />
                <Button
                  onClick={() => {
                    localStorage.removeItem('translations-check')
                    window.location.reload()
                  }}
                >
                  {c('returnToApp')}
                </Button>
              </>
            ) : null}
          </div>
        }
      />
      {/* Height: 100vh - page padding - header */}
      <div className={styles.resultsContainer}>
        {Object.entries(groupedMissingTranslations).map(
          ([language, modules]) => (
            <TranslationCard
              key={language}
              language={language as SupportedLanguageKeys}
              modules={modules}
            />
          ),
        )}
      </div>
    </div>
  )
}

export default TranslationTools
