import { mdiChartTimelineVariant, mdiDomain, mdiOfficeBuildingCogOutline } from '@mdi/js'
import Head from 'next/head'
import React, { ReactElement, useEffect, useMemo, useState } from 'react'
import { Field, Form, Formik } from 'formik'
import { useRouter } from 'next/router'

import BaseButton from '../../components/BaseButton'
import BaseButtons from '../../components/BaseButtons'
import BaseDivider from '../../components/BaseDivider'
import CardBox from '../../components/CardBox'
import ConnectedEntityCard from '../../components/ConnectedEntityCard'
import TenantStatusChip from '../../components/TenantStatusChip'
import ConnectedEntityNotice from '../../components/ConnectedEntityNotice'
import FormField from '../../components/FormField'
import NotificationBar from '../../components/NotificationBar'
import SectionMain from '../../components/SectionMain'
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton'
import { getPageTitle } from '../../config'
import {
  emptyOrganizationTenantSummary,
  getTenantManageHref,
  getTenantSetupHref,
  getTenantViewHref,
  loadLinkedTenantSummary,
} from '../../helpers/organizationTenants'
import { hasPermission } from '../../helpers/userPermissions'
import LayoutAuthenticated from '../../layouts/Authenticated'
import { fetch, update } from '../../stores/organizations/organizationsSlice'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'

const emptyOrganization = {
  name: '',
}

const EditOrganizationsPage = () => {
  const router = useRouter()
  const dispatch = useAppDispatch()
  const { organizations } = useAppSelector((state) => state.organizations)
  const { currentUser } = useAppSelector((state) => state.auth)

  const [initialValues, setInitialValues] = useState(emptyOrganization)
  const [submitMode, setSubmitMode] = useState<'list' | 'tenant'>('list')
  const [linkedTenantSummary, setLinkedTenantSummary] = useState(emptyOrganizationTenantSummary)

  const organizationId = useMemo(
    () => (typeof router.query.id === 'string' ? router.query.id : ''),
    [router.query.id],
  )
  const tenantIdFromQuery = useMemo(
    () => (typeof router.query.tenantId === 'string' ? router.query.tenantId : ''),
    [router.query.tenantId],
  )
  const tenantNameFromQuery = useMemo(
    () => (typeof router.query.tenantName === 'string' ? router.query.tenantName : ''),
    [router.query.tenantName],
  )

  const canReadTenants = hasPermission(currentUser, 'READ_TENANTS')
  const canUpdateTenants = hasPermission(currentUser, 'UPDATE_TENANTS')
  const linkedTenants = Array.isArray(linkedTenantSummary.rows) ? linkedTenantSummary.rows : []

  useEffect(() => {
    if (!organizationId) return

    dispatch(fetch({ id: organizationId }))
  }, [dispatch, organizationId])

  useEffect(() => {
    if (!organizations || typeof organizations !== 'object' || Array.isArray(organizations)) {
      return
    }

    setInitialValues({
      name: organizations.name || '',
    })
  }, [organizations])

  useEffect(() => {
    if (!organizationId) {
      setLinkedTenantSummary(emptyOrganizationTenantSummary)
      return
    }

    let isActive = true

    loadLinkedTenantSummary(organizationId)
      .then((summary) => {
        if (isActive) {
          setLinkedTenantSummary(summary)
        }
      })
      .catch((error) => {
        console.error('Failed to load linked tenants for organization edit:', error)

        if (isActive) {
          setLinkedTenantSummary(emptyOrganizationTenantSummary)
        }
      })

    return () => {
      isActive = false
    }
  }, [organizationId])

  const handleSubmit = async (data) => {
    const resultAction = await dispatch(update({ id: organizationId, data }))

    if (!update.fulfilled.match(resultAction)) {
      return
    }

    if (submitMode === 'tenant' && organizationId) {
      await router.push(getTenantSetupHref(organizationId, data.name || initialValues.name || ''))
      return
    }

    await router.push('/organizations/organizations-list')
  }

  return (
    <>
      <Head>
        <title>{getPageTitle('Edit organization')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="Edit organization" main>
          {''}
        </SectionTitleLineWithButton>

        <NotificationBar
          color="info"
          icon={mdiOfficeBuildingCogOutline}
          button={
            <BaseButton
              href={getTenantSetupHref(organizationId, initialValues.name || organizations?.name || '')}
              color="info"
              label="Open tenant setup"
              small
            />
          }
        >
          Organizations stay lightweight here. Tenant settings like slug, domain, timezone, currency, and activation
          still live under <strong>Tenants</strong>, so you can jump straight into tenant setup after saving changes.
        </NotificationBar>

        <CardBox>
          <Formik enableReinitialize initialValues={initialValues} onSubmit={(values) => handleSubmit(values)}>
            {({ values }) => {
              const organizationNameForLinks = values.name || initialValues.name || organizations?.name || ''

              return (
                <Form>
                  <ConnectedEntityNotice
                    contextLabel={tenantIdFromQuery ? tenantNameFromQuery || 'Tenant flow' : undefined}
                    contextHref={tenantIdFromQuery ? getTenantViewHref(tenantIdFromQuery, organizationId, organizationNameForLinks) : undefined}
                    contextActionLabel="View tenant"
                    description={
                      <>
                        Organizations stay lightweight here, while tenants hold shared settings like slug, domain,
                        timezone, currency, and activation.
                        {linkedTenantSummary.count
                          ? ` ${linkedTenantSummary.count} tenant${linkedTenantSummary.count === 1 ? '' : 's'} currently connected.`
                          : ' No tenant is connected yet.'}
                      </>
                    }
                    actions={[
                      {
                        href: getTenantSetupHref(organizationId, organizationNameForLinks),
                        label: linkedTenantSummary.count ? 'Add tenant link' : 'Create tenant link',
                        color: 'info',
                      },
                      ...(tenantIdFromQuery
                        ? canUpdateTenants
                          ? [
                              {
                                href: getTenantManageHref(tenantIdFromQuery, organizationId, organizationNameForLinks),
                                label: 'Back to tenant',
                                color: 'white',
                                outline: true,
                              },
                            ]
                          : canReadTenants
                            ? [
                                {
                                  href: getTenantViewHref(tenantIdFromQuery, organizationId, organizationNameForLinks),
                                  label: 'View tenant',
                                  color: 'white',
                                  outline: true,
                                },
                              ]
                            : []
                        : []),
                    ]}
                  />

                  <div className="mb-6 rounded-xl border border-dashed border-gray-300 bg-gray-50 p-4 dark:border-dark-700 dark:bg-dark-800">
                    <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                      <div className="min-w-0">
                        <p className="font-semibold text-gray-700 dark:text-gray-100">Linked tenants</p>
                        <p className="mt-1 text-sm leading-6 text-gray-600 dark:text-gray-300">
                          {linkedTenantSummary.count
                            ? `${linkedTenantSummary.count} tenant${linkedTenantSummary.count === 1 ? '' : 's'} currently linked to this organization.`
                            : 'This organization is not linked to a tenant yet. Create or connect one from here to keep the workspace fully wired.'}
                        </p>
                      </div>
                      <BaseButton
                        href={getTenantSetupHref(organizationId, organizationNameForLinks)}
                        color="info"
                        label={linkedTenantSummary.count ? 'Create another tenant link' : 'Create tenant & link'}
                        className="w-full sm:w-auto"
                      />
                    </div>

                    {linkedTenants.length ? (
                      <div className="mt-4 grid gap-3 sm:grid-cols-2">
                        {linkedTenants.map((tenant: any) => (
                          <ConnectedEntityCard
                            key={tenant.id}
                            entityLabel="Tenant"
                            title={tenant.name || 'Unnamed tenant'}
                            badges={[<TenantStatusChip key={`tenant-status-${tenant.id}`} isActive={tenant.is_active} />]}
                            details={[
                              { label: 'Slug', value: tenant.slug },
                              { label: 'Domain', value: tenant.primary_domain },
                              { label: 'Timezone', value: tenant.timezone },
                              { label: 'Currency', value: tenant.default_currency },
                            ]}
                            actions={[
                              ...(canReadTenants
                                ? [
                                    {
                                      href: getTenantViewHref(tenant.id, organizationId, organizationNameForLinks),
                                      label: 'View tenant',
                                      color: 'info',
                                      outline: true,
                                    },
                                  ]
                                : []),
                              ...(canUpdateTenants
                                ? [
                                    {
                                      href: getTenantManageHref(tenant.id, organizationId, organizationNameForLinks),
                                      label: 'Manage link',
                                      color: 'info',
                                    },
                                  ]
                                : []),
                            ]}
                            helperText={canUpdateTenants ? 'Context preserved when managing this tenant link.' : undefined}
                          />
                        ))}
                      </div>
                    ) : (
                      <div className="mt-4 rounded-xl border border-gray-200 bg-white px-4 py-4 text-sm text-gray-600 dark:border-dark-700 dark:bg-dark-900 dark:text-gray-300">
                        Create a tenant from here to preselect this organization automatically, then save the tenant to establish the link.
                      </div>
                    )}
                  </div>

                  <FormField
                    label="Organization name"
                    labelFor="name"
                    help="Update the workspace name here, then continue to tenant setup if you need to attach or configure tenant-level settings."
                  >
                    <Field name="name" id="name" placeholder="Acme Operations" />
                  </FormField>

                  <BaseDivider />

                  <div className="mb-6 rounded-xl border border-dashed border-gray-300 bg-gray-50 p-4 text-sm text-gray-600 dark:border-dark-700 dark:bg-dark-800 dark:text-gray-300">
                    <div className="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
                      <div className="min-w-0">
                        <p className="font-semibold text-gray-700 dark:text-gray-100">Need tenant settings too?</p>
                        <p className="mt-1 leading-6">
                          Save this organization, then continue into tenant setup to link it and manage shared settings like
                          slug, domain, timezone, currency, and activation.
                        </p>
                      </div>
                      <BaseButton
                        href={getTenantSetupHref(organizationId, organizationNameForLinks)}
                        color="white"
                        outline
                        icon={mdiDomain}
                        label="Review tenant form"
                        className="w-full sm:w-auto"
                      />
                    </div>
                  </div>

                  <BaseButtons
                    type="justify-start sm:justify-end"
                    className="items-stretch sm:items-center"
                    classAddon="w-full sm:w-auto mr-0 sm:mr-3 mb-3"
                  >
                    <BaseButton
                      type="submit"
                      color="success"
                      label="Save & set up tenant"
                      onClick={() => setSubmitMode('tenant')}
                    />
                    <BaseButton
                      type="submit"
                      color="info"
                      label="Save changes"
                      onClick={() => setSubmitMode('list')}
                    />
                    <BaseButton type="reset" color="info" outline label="Reset" />
                    <BaseButton
                      type="reset"
                      color="danger"
                      outline
                      label="Cancel"
                      onClick={() => router.push('/organizations/organizations-list')}
                    />
                  </BaseButtons>
                </Form>
              )
            }}
          </Formik>
        </CardBox>
      </SectionMain>
    </>
  )
}

EditOrganizationsPage.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated permission={'UPDATE_ORGANIZATIONS'}>{page}</LayoutAuthenticated>
}

export default EditOrganizationsPage
