import React, { useMemo, useState } from 'react';
import styled from 'styled-components';
import { isAxiosError } from 'axios';
import { useNavigate } from 'react-router-dom';
import { useLocale } from '@/app/providers/LocaleProvider';
import { useAuthStore } from '@/features/auth/store/authStore';
import { extractApiErrorMessage } from '@/shared/utils/apiErrors';
import { AppLayout } from '@/shared/components/layout/AppLayout';
import { Button, Input, Select, Spinner, Textarea } from '@/shared/components/ui';
import { ROUTES } from '@/shared/constants/routes';
import { AssigneePicker } from '@/features/tickets/components/AssigneePicker';
import { useCreateTicket } from '@/features/tickets/hooks/useCreateTicket';
import { useTicketDepartments } from '@/features/tickets/hooks/useTicketDepartments';
import { useTicketFormOptions } from '@/features/tickets/hooks/useTicketFormOptions';
import { localizedName } from '@/features/tickets/utils/ticketDisplay';
import type { AssignableUser } from '@/features/tickets/types/ticketForm.types';

const Title = styled.h1`
  font-size: ${({ theme }) => theme.typography.fontSize['2xl']};
  margin-bottom: ${({ theme }) => theme.spacing[6]};
  text-align: start;
`;

const Form = styled.form`
  display: flex;
  flex-direction: column;
  gap: ${({ theme }) => theme.spacing[5]};
  max-width: 720px;
`;

const Actions = styled.div`
  display: flex;
  gap: ${({ theme }) => theme.spacing[3]};
  flex-wrap: wrap;
`;

const ErrorBanner = styled.div`
  padding: ${({ theme }) => theme.spacing[4]};
  border-radius: ${({ theme }) => theme.borderRadius.md};
  background: ${({ theme }) => theme.colors.errorLight};
  color: ${({ theme }) => theme.colors.error};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  text-align: start;
`;

const Centered = styled.div`
  display: flex;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[3]};
  color: ${({ theme }) => theme.colors.text.secondary};
`;

const CreateTicketPage: React.FC = () => {
  const { t, locale } = useLocale();
  const navigate = useNavigate();
  const user = useAuthStore((state) => state.user);
  const {
    departments,
    departmentId,
    setDepartmentId,
    companyId,
    setCompanyId,
    companies,
    isSuperAdmin,
    isLoadingCompanies,
    isLoadingDepartments,
    hasCompany,
    hasDepartments,
  } = useTicketDepartments();

  const [subject, setSubject] = useState('');
  const [description, setDescription] = useState('');
  const [categoryId, setCategoryId] = useState('');
  const [subcategoryId, setSubcategoryId] = useState('');
  const [priorityId, setPriorityId] = useState('');
  const [assignee, setAssignee] = useState<AssignableUser | null>(null);
  const [formError, setFormError] = useState<string | null>(null);

  const formOptionsQuery = useTicketFormOptions(departmentId || undefined);
  const createMutation = useCreateTicket();

  const categories = useMemo(
    () => formOptionsQuery.data?.categories ?? [],
    [formOptionsQuery.data?.categories],
  );
  const priorities = useMemo(
    () => formOptionsQuery.data?.priorities ?? [],
    [formOptionsQuery.data?.priorities],
  );

  const subcategories = useMemo(() => {
    const category = categories.find((item) => item.id === categoryId);
    return category?.subcategories ?? [];
  }, [categories, categoryId]);

  const optionsErrorMessage = useMemo(() => {
    if (!formOptionsQuery.isError) {
      return null;
    }

    if (isAxiosError(formOptionsQuery.error)) {
      const apiMessage = formOptionsQuery.error.response?.data;
      if (
        typeof apiMessage === 'object' &&
        apiMessage !== null &&
        'message' in apiMessage &&
        typeof apiMessage.message === 'string'
      ) {
        return apiMessage.message;
      }
    }

    return t('tickets:createForm.optionsError');
  }, [formOptionsQuery.error, formOptionsQuery.isError, t]);

  const handleSubmit = async (event: React.FormEvent) => {
    event.preventDefault();
    setFormError(null);

    if (!departmentId) {
      setFormError(t('tickets:createForm.departmentRequired'));
      return;
    }

    if (subject.trim().length < 5) {
      setFormError(t('tickets:createForm.subjectMin'));
      return;
    }

    if (description.trim().length < 10) {
      setFormError(t('tickets:createForm.descriptionMin'));
      return;
    }

    try {
      const ticket = await createMutation.mutateAsync({
        department_id: departmentId,
        subject: subject.trim(),
        description: description.trim(),
        category_id: categoryId || undefined,
        subcategory_id: subcategoryId || undefined,
        priority_id: priorityId || undefined,
        assignee_id: assignee?.id,
      });

      navigate(ROUTES.TICKET_DETAIL(ticket.id));
    } catch (error) {
      const apiMessage = isAxiosError(error)
        ? extractApiErrorMessage(error.response?.data)
        : undefined;
      setFormError(apiMessage ?? (error instanceof Error ? error.message : t('tickets:createForm.error')));
    }
  };

  if (!user) {
    return (
      <AppLayout>
        <Centered role="status">
          <Spinner />
        </Centered>
      </AppLayout>
    );
  }

  if (isLoadingDepartments || isLoadingCompanies) {
    return (
      <AppLayout>
        <Centered role="status">
          <Spinner />
          <span>{t('tickets:createForm.loadingDepartments')}</span>
        </Centered>
      </AppLayout>
    );
  }

  if (isSuperAdmin && !hasCompany) {
    return (
      <AppLayout>
        <Title>{t('tickets:create')}</Title>
        <Form>
          <Select
            label={t('tickets:createForm.company')}
            value={companyId}
            onChange={(event) => setCompanyId(event.target.value)}
            options={[
              { value: '', label: t('admin:users.selectCompany') },
              ...companies.map((company) => ({
                value: company.id,
                label: company.name,
              })),
            ]}
            fullWidth
            required
          />
        </Form>
      </AppLayout>
    );
  }

  if (!hasDepartments) {
    return (
      <AppLayout>
        <Title>{t('tickets:create')}</Title>
        <ErrorBanner role="alert">{t('tickets:createForm.noDepartments')}</ErrorBanner>
      </AppLayout>
    );
  }

  return (
    <AppLayout>
      <Title>{t('tickets:create')}</Title>

      {formOptionsQuery.isLoading && departmentId ? (
        <Centered role="status">
          <Spinner />
          <span>{t('tickets:createForm.loadingOptions')}</span>
        </Centered>
      ) : (
        <Form onSubmit={(event) => void handleSubmit(event)}>
          {formError && <ErrorBanner role="alert">{formError}</ErrorBanner>}
          {optionsErrorMessage && <ErrorBanner role="alert">{optionsErrorMessage}</ErrorBanner>}

          {isSuperAdmin && (
            <Select
              label={t('tickets:createForm.company')}
              value={companyId}
              onChange={(event) => {
                setCompanyId(event.target.value);
                setCategoryId('');
                setSubcategoryId('');
                setPriorityId('');
                setAssignee(null);
              }}
              options={companies.map((company) => ({
                value: company.id,
                label: company.name,
              }))}
              fullWidth
              required
            />
          )}

          <Select
            label={t('tickets:createForm.department')}
            value={departmentId}
            onChange={(event) => {
              setDepartmentId(event.target.value);
              setCategoryId('');
              setSubcategoryId('');
              setPriorityId('');
              setAssignee(null);
            }}
            options={[
              { value: '', label: t('admin:users.selectDepartment') },
              ...departments.map((dept) => ({
                value: dept.id,
                label: dept.name,
              })),
            ]}
            fullWidth
            required
          />

          <Input
            label={t('tickets:fields.subject')}
            value={subject}
            onChange={(event) => setSubject(event.target.value)}
            fullWidth
            required
          />

          <Textarea
            label={t('tickets:fields.description')}
            value={description}
            onChange={(event) => setDescription(event.target.value)}
            rows={6}
            fullWidth
            required
          />

          <Select
            label={t('tickets:fields.category')}
            value={categoryId}
            onChange={(event) => {
              setCategoryId(event.target.value);
              setSubcategoryId('');
            }}
            options={[
              { value: '', label: t('tickets:createForm.optional') },
              ...categories.map((category) => ({
                value: category.id,
                label: localizedName(category, locale),
              })),
            ]}
            fullWidth
            disabled={formOptionsQuery.isError}
          />

          <Select
            label={t('tickets:fields.subcategory')}
            value={subcategoryId}
            onChange={(event) => setSubcategoryId(event.target.value)}
            options={[
              { value: '', label: t('tickets:createForm.optional') },
              ...subcategories.map((sub) => ({
                value: sub.id,
                label: localizedName(sub, locale),
              })),
            ]}
            fullWidth
            disabled={!categoryId || formOptionsQuery.isError}
          />

          <Select
            label={t('tickets:fields.priority')}
            value={priorityId}
            onChange={(event) => setPriorityId(event.target.value)}
            options={[
              { value: '', label: t('tickets:createForm.defaultPriority') },
              ...priorities.map((priority) => ({
                value: priority.id,
                label: localizedName(priority, locale),
              })),
            ]}
            fullWidth
            disabled={formOptionsQuery.isError}
          />

          {departmentId && (
            <AssigneePicker
              departmentId={departmentId}
              value={assignee}
              onChange={setAssignee}
            />
          )}

          <Actions>
            <Button
              type="submit"
              variant="primary"
              loading={createMutation.isPending}
              disabled={formOptionsQuery.isError}
            >
              {t('tickets:create')}
            </Button>
            <Button type="button" variant="ghost" onClick={() => navigate(ROUTES.TICKETS)}>
              {t('common:actions.cancel')}
            </Button>
          </Actions>
        </Form>
      )}
    </AppLayout>
  );
};

export default CreateTicketPage;
