import { createFileRoute, Link, useNavigate } from '@tanstack/react-router'
import { RequireAuth } from '../../../auth'
import {
  Alert,
  Badge,
  Box,
  Button,
  Card,
  Container,
  Group,
  Modal,
  NumberInput,
  Select,
  Stack,
  Table,
  Text,
  Textarea,
  TextInput,
  Title,
} from '@pikku/mantine/core'
import { useDisclosure } from '@mantine/hooks'
import { useMemo, useState } from 'react'
import { m, mKey } from '@/i18n/messages'
import { useLocale, getLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import { AlertCircle, Plus } from 'lucide-react'
import { usePikkuQuery, usePikkuMutation } from '@germantax/functions-sdk/pikku/api.gen'

const ROLES = ['managing_director', 'shareholder', 'angel'] as const
type Role = (typeof ROLES)[number]

type AddMemberFormState = {
  email: string
  displayName: string
  role: Role
  shares: number | ''
}

const EMPTY_MEMBER_FORM: AddMemberFormState = {
  email: '',
  displayName: '',
  role: 'shareholder',
  shares: '',
}

function CompanyPage() {
  const { companyId } = Route.useParams()
  useLocale()
  const navigate = useNavigate()
  const company = usePikkuQuery('getCompany', { companyId })
  const members = usePikkuQuery('listMembers', { companyId })
  const resolutions = usePikkuQuery('listResolutions', { companyId })
  const templates = usePikkuQuery('listResolutionTemplates', undefined as never)

  const [memberModalOpened, { open: openMemberModal, close: closeMemberModal }] =
    useDisclosure(false)
  const [resolutionModalOpened, { open: openResolutionModal, close: closeResolutionModal }] =
    useDisclosure(false)

  const [memberForm, setMemberForm] = useState<AddMemberFormState>(EMPTY_MEMBER_FORM)
  const [memberError, setMemberError] = useState<string | null>(null)

  const [templateKey, setTemplateKey] = useState<string | null>(null)
  const [resolutionTitle, setResolutionTitle] = useState('')
  const [fieldValues, setFieldValues] = useState<Record<string, unknown>>({})
  const [resolutionError, setResolutionError] = useState<string | null>(null)

  const addMember = usePikkuMutation('addMember', {
    onSuccess: () => {
      setMemberForm(EMPTY_MEMBER_FORM)
      setMemberError(null)
      closeMemberModal()
      members.refetch()
      company.refetch()
    },
    onError: (err: unknown) => {
      setMemberError(err instanceof Error ? err.message : String(err))
    },
  })
  const removeMember = usePikkuMutation('removeMember', {
    onSuccess: () => {
      members.refetch()
      company.refetch()
    },
  })
  const archiveResolution = usePikkuMutation('archiveResolution', {
    onSuccess: () => resolutions.refetch(),
  })
  const publishResolution = usePikkuMutation('publishResolution', {
    onSuccess: () => resolutions.refetch(),
  })
  const createResolution = usePikkuMutation('createResolution', {
    onSuccess: ({ resolutionId }) => {
      closeResolutionModal()
      navigate({
        to: '/companies/$companyId/resolutions/$resolutionId',
        params: { companyId, resolutionId } as never,
      })
    },
    onError: (err: unknown) => {
      setResolutionError(err instanceof Error ? err.message : String(err))
    },
  })

  const isMd = company.data?.myRole === 'managing_director'
  const totalShares = company.data?.totalShares ?? 0
  const assignedShares = company.data?.assignedShares ?? 0
  const remainingShares = Math.max(0, totalShares - assignedShares)

  const lang = getLocale()?.startsWith('de') ? 'de' : 'en'
  const labelOf = (f: { labelDe: string; labelEn: string }) =>
    lang === 'de' ? f.labelDe : f.labelEn
  const template = useMemo(
    () => templates.data?.find((tpl) => tpl.key === templateKey),
    [templates.data, templateKey],
  )

  const handleOpenMemberModal = () => {
    setMemberForm(EMPTY_MEMBER_FORM)
    setMemberError(null)
    openMemberModal()
  }

  const handleSubmitMember = (e: React.FormEvent) => {
    e.preventDefault()
    if (!memberForm.email || !memberForm.displayName) return
    setMemberError(null)
    addMember.mutate({
      companyId,
      email: memberForm.email,
      displayName: memberForm.displayName,
      role: memberForm.role,
      shares: memberForm.shares === '' ? null : Number(memberForm.shares),
    })
  }

  const handleOpenResolutionModal = () => {
    setTemplateKey(null)
    setResolutionTitle('')
    setFieldValues({})
    setResolutionError(null)
    openResolutionModal()
  }

  const handleSubmitResolution = (e: React.FormEvent) => {
    e.preventDefault()
    if (!templateKey || !resolutionTitle) return
    setResolutionError(null)
    createResolution.mutate({
      companyId,
      templateKey,
      title: resolutionTitle,
      fieldValues,
    })
  }

  return (
    <Container size="lg" py="xl">
      <Stack gap="xl">
        {company.error && <Alert color="red">{asI18n(String(company.error.message))}</Alert>}
        {company.data && (
          <Group justify="space-between" align="flex-end" wrap="wrap">
            <Stack gap={2}>
              <Title order={2}>{asI18n(company.data.name)}</Title>
              {company.data.registryNo && (
                <Text c="dimmed" size="sm">{asI18n(company.data.registryNo)}</Text>
              )}
              {(company.data.addressLine1 || company.data.town) && (
                <Text c="dimmed" size="sm">
                  {asI18n(
                    [
                      company.data.addressLine1,
                      company.data.addressLine2,
                      [company.data.postcode, company.data.town].filter(Boolean).join(' '),
                      company.data.country,
                    ]
                      .filter(Boolean)
                      .join(', '),
                  )}
                </Text>
              )}
              {totalShares > 0 && (
                <Text c="dimmed" size="sm">
                  {m.app_companies_shares_assigned({
                    assigned: assignedShares,
                    total: totalShares,
                  })}
                </Text>
              )}
            </Stack>
            <Badge size="lg">{mKey(`app.companies.rolesEnum.${company.data.myRole}`)}</Badge>
          </Group>
        )}

        <Card withBorder radius="md" p="md">
          <Stack gap="sm">
            <Group justify="space-between">
              <Title order={4}>{m.app_companies_members()}</Title>
              {isMd && (
                <Button
                  size="sm"
                  leftSection={<Plus size={16} aria-hidden="true" />}
                  onClick={handleOpenMemberModal}
                >
                  {m.app_companies_add_member()}
                </Button>
              )}
            </Group>
            <Table withTableBorder withColumnBorders>
              <Table.Thead>
                <Table.Tr>
                  <Table.Th>{m.app_companies_member_display_name()}</Table.Th>
                  <Table.Th>{m.app_companies_member_email()}</Table.Th>
                  <Table.Th>{m.app_companies_role()}</Table.Th>
                  <Table.Th>{m.app_companies_member_shares()}</Table.Th>
                  <Table.Th />
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {members.data?.map((member) => (
                  <Table.Tr key={member.memberId}>
                    <Table.Td>{member.displayName}</Table.Td>
                    <Table.Td>{member.email}</Table.Td>
                    <Table.Td>{mKey(`app.companies.rolesEnum.${member.role}`)}</Table.Td>
                    <Table.Td>{member.shares ?? '—'}</Table.Td>
                    <Table.Td>
                      {isMd && (
                        <Button
                          variant="subtle"
                          color="red"
                          size="xs"
                          onClick={() =>
                            removeMember.mutate({ companyId, memberId: member.memberId })
                          }
                        >
                          {m.app_companies_remove()}
                        </Button>
                      )}
                    </Table.Td>
                  </Table.Tr>
                ))}
              </Table.Tbody>
            </Table>
          </Stack>
        </Card>

        <Card withBorder radius="md" p="md">
          <Stack gap="sm">
            <Group justify="space-between">
              <Title order={4}>{m.app_resolutions_title()}</Title>
              <Button
                leftSection={<Plus size={16} aria-hidden="true" />}
                onClick={handleOpenResolutionModal}
              >
                {m.app_resolutions_new()}
              </Button>
            </Group>

            {resolutions.data && resolutions.data.length === 0 && (
              <Text c="dimmed">{m.app_resolutions_empty()}</Text>
            )}

            <Stack gap="xs">
              {resolutions.data?.map((r) => (
                <Card key={r.resolutionId} withBorder radius="sm" p="sm">
                  <Group justify="space-between" wrap="nowrap">
                    <Stack gap={2}>
                      <Group gap="xs">
                        <Text fw={600}>{asI18n(r.title)}</Text>
                        <Badge color={r.status === 'published' ? 'green' : r.status === 'archived' ? 'gray' : 'blue'}>
                          {mKey(`app.resolutions.${r.status}`)}
                        </Badge>
                      </Group>
                      <Text size="xs" c="dimmed">{asI18n(r.templateKey)}</Text>
                    </Stack>
                    <Group gap="xs">
                      <Button
                        component={Link}
                        to="/companies/$companyId/resolutions/$resolutionId"
                        params={{ companyId, resolutionId: r.resolutionId } as any}
                        variant="light"
                        size="xs"
                      >
                        {m.app_companies_open()}
                      </Button>
                      {isMd && r.status === 'draft' && (
                        <Button
                          size="xs"
                          color="green"
                          onClick={() => publishResolution.mutate({ resolutionId: r.resolutionId })}
                          loading={publishResolution.isPending}
                        >
                          {m.app_resolutions_publish()}
                        </Button>
                      )}
                      {isMd && r.status !== 'archived' && (
                        <Button
                          size="xs"
                          variant="subtle"
                          color="gray"
                          onClick={() => archiveResolution.mutate({ resolutionId: r.resolutionId })}
                        >
                          {m.app_resolutions_archive()}
                        </Button>
                      )}
                    </Group>
                  </Group>
                </Card>
              ))}
            </Stack>
          </Stack>
        </Card>
      </Stack>

      <Modal
        opened={memberModalOpened}
        onClose={closeMemberModal}
        title={m.app_companies_add_member_title()}
        size="md"
        centered
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Box component="form" onSubmit={handleSubmitMember} noValidate>
          <Stack gap="md">
            {memberError && (
              <Alert
                role="alert"
                color="red"
                variant="light"
                icon={<AlertCircle size={18} aria-hidden="true" />}
                title={m.app_companies_errors_add_member_title()}
              >
                {asI18n(memberError)}
              </Alert>
            )}
            <Stack gap="sm">
              <TextInput
                label={m.app_companies_member_email()}
                type="email"
                value={memberForm.email}
                onChange={(e) =>
                  setMemberForm({ ...memberForm, email: e.currentTarget.value })
                }
                required
              />
              <TextInput
                label={m.app_companies_member_display_name()}
                value={memberForm.displayName}
                onChange={(e) =>
                  setMemberForm({ ...memberForm, displayName: e.currentTarget.value })
                }
                required
              />
              <Select
                label={m.app_companies_member_role()}
                data={ROLES.map((r) => ({
                  value: r,
                  label: mKey(`app.companies.rolesEnum.${r}`),
                }))}
                value={memberForm.role}
                onChange={(v) => v && setMemberForm({ ...memberForm, role: v as Role })}
                allowDeselect={false}
              />
              <NumberInput
                label={m.app_companies_member_shares()}
                description={
                  totalShares > 0
                    ? remainingShares > 0
                      ? m.app_companies_shares_remaining({ count: remainingShares })
                      : m.app_companies_shares_fully_assigned()
                    : undefined
                }
                value={memberForm.shares}
                onChange={(v) =>
                  setMemberForm({
                    ...memberForm,
                    shares: typeof v === 'number' ? v : '',
                  })
                }
                min={0}
                max={totalShares > 0 ? remainingShares : undefined}
                step={1}
                allowDecimal={false}
                disabled={totalShares > 0 && remainingShares === 0}
              />
            </Stack>
            <Group justify="flex-end" gap="sm">
              <Button variant="subtle" onClick={closeMemberModal} type="button">
                {m.app_companies_cancel()}
              </Button>
              <Button type="submit" loading={addMember.isPending}>
                {m.app_companies_add_member()}
              </Button>
            </Group>
          </Stack>
        </Box>
      </Modal>

      <Modal
        opened={resolutionModalOpened}
        onClose={closeResolutionModal}
        title={m.app_resolutions_new_title()}
        size="lg"
        centered
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Box component="form" onSubmit={handleSubmitResolution} noValidate>
          <Stack gap="md">
            {resolutionError && (
              <Alert
                role="alert"
                color="red"
                variant="light"
                icon={<AlertCircle size={18} aria-hidden="true" />}
                title={m.app_resolutions_errors_create_title()}
              >
                {asI18n(resolutionError)}
              </Alert>
            )}
            <Select
              label={m.app_resolutions_select_template()}
              data={
                templates.data?.map((tpl) => ({
                  value: tpl.key,
                  label: lang === 'de' ? tpl.titleDe : tpl.titleEn,
                })) ?? []
              }
              value={templateKey}
              onChange={(v) => {
                setTemplateKey(v)
                setFieldValues({})
                const tpl = templates.data?.find((x) => x.key === v)
                if (tpl) setResolutionTitle(lang === 'de' ? tpl.titleDe : tpl.titleEn)
              }}
              searchable
              required
            />
            <TextInput
              label={m.app_resolutions_resolution_title()}
              value={resolutionTitle}
              onChange={(e) => setResolutionTitle(e.currentTarget.value)}
              required
            />

            {template && (
              <Stack gap="xs">
                <Text fw={600}>{m.app_resolutions_fields()}</Text>
                {template.fields.map((f) => {
                  const v = fieldValues[f.key]
                  if (f.type === 'textarea') {
                    return (
                      <Textarea
                        key={f.key}
                        label={asI18n(labelOf(f))}
                        required={f.required}
                        value={(v as string) ?? ''}
                        onChange={(e) =>
                          setFieldValues({ ...fieldValues, [f.key]: e.currentTarget.value })
                        }
                        autosize
                        minRows={2}
                      />
                    )
                  }
                  if (f.type === 'number' || f.type === 'currency') {
                    return (
                      <NumberInput
                        key={f.key}
                        label={asI18n(labelOf(f))}
                        required={f.required}
                        value={typeof v === 'number' ? v : ''}
                        onChange={(val) =>
                          setFieldValues({
                            ...fieldValues,
                            [f.key]: typeof val === 'number' ? val : 0,
                          })
                        }
                        min={0}
                        decimalScale={f.type === 'currency' ? 2 : 0}
                      />
                    )
                  }
                  return (
                    <TextInput
                      key={f.key}
                      type={f.type === 'date' ? 'date' : 'text'}
                      label={asI18n(labelOf(f))}
                      required={f.required}
                      value={(v as string) ?? ''}
                      onChange={(e) =>
                        setFieldValues({ ...fieldValues, [f.key]: e.currentTarget.value })
                      }
                    />
                  )
                })}
              </Stack>
            )}

            <Group justify="flex-end" gap="sm">
              <Button variant="subtle" onClick={closeResolutionModal} type="button">
                {m.app_companies_cancel()}
              </Button>
              <Button
                type="submit"
                disabled={!templateKey || !resolutionTitle}
                loading={createResolution.isPending}
              >
                {m.app_resolutions_create()}
              </Button>
            </Group>
          </Stack>
        </Box>
      </Modal>
    </Container>
  )
}

export const Route = createFileRoute('/companies/$companyId/')({
  component: () => <RequireAuth><CompanyPage /></RequireAuth>,
})
