import React, { useState } from "react";
import { useParams } from "react-router-dom";

import Card from "../../../components/Card";
import CardActions from "../../../components/Card/CardActions";
import CardCancelButton from "../../../components/Card/CardCancelButton";
import CardContent from "../../../components/Card/CardContent";
import CardFieldAddress from "../../../components/Card/CardFieldAddress";
import CardFieldText from "../../../components/Card/CardFieldText";
import CardHeader from "../../../components/Card/CardHeader";
import CardRow from "../../../components/Card/CardRow";
import CardSaveButton from "../../../components/Card/CardSaveButton";
import { useApi } from "../../../contexts/ApiContext";
import { useI18n } from "../../../contexts/I18nContext";
import { useUser } from "../../../contexts/UserContext";
import { getFormErrors, ValidationError } from "../../../util/form_validation";
import { hasPermission } from "../../../util/has_permission";
import { CustomerType, MemberDetail } from "../types/member";

export interface MemberCardProps {
  member: MemberDetail;
  onUpdated: (member: MemberDetail) => void;
}

export interface MemberDetailCardFormValues {
  customer_type: CustomerType;
  company_name: string;
  given_name: string;
  family_name: string;
  email: string;
  phone: string;
  street_address: string;
  street_address2: string;
  postal_code: string;
  city: string;
  country_code: string;
  region: string;
  care_of: string;
  billing_address?: Partial<{
    street_address: string;
    street_address2: string;
    postal_code: string;
    city: string;
    country_code: string;
    region: string;
    care_of: string;
  }>;
}

export const MemberDetailCard: React.FC<MemberCardProps> = (props) => {
  const params = useParams();
  const api = useApi();
  const { user } = useUser();
  const { t } = useI18n();
  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});

  const handleSave = async (values: MemberDetailCardFormValues) => {
    setFieldErrors({});
    const body = { ...values };

    const addressFields = {
      street_address: values.street_address,
      street_address2: values.street_address2,
      postal_code: values.postal_code,
      city: values.city,
      country_code: values.country_code,
      region: values.region,
      care_of: values.care_of,
    };

    // Convert all empty string fields to null
    Object.entries(body).forEach(([key, value]) => {
      if (value === "") {
        // @ts-expect-error - we know that body has these properties
        body[key] = null;
      }
    });

    if (Object.values(addressFields).some((value) => value)) {
      body.billing_address = {};
      Object.entries(addressFields).forEach(([key, value]) => {
        // @ts-expect-error - we know that body has a billing_address property
        if (value != null && value !== "") body.billing_address[key] = value;
      });
    }

    const action = api.operations["member.member:update"];
    if (!action) {
      throw new Error('Invalid action "member.member:update".');
    }

    const response = await action.call({
      params,
      body,
    });

    if (response.ok) {
      const updatedMember = await response.json();
      props.onUpdated(updatedMember);
      return t("Member updated successfully.");
    } else {
      console.error("[MEMBERSHIP_DETAIL_CARD]", response);
      const errors = await getFormErrors(response);
      if (errors) {
        setFieldErrors(errors.fieldErrors);
        throw new ValidationError(
          errors.formErrors[0] ?? t("Invalid form input. Please correct the highlighted fields."),
          errors,
        );
      }
      throw new Error("updating member fields.");
    }
  };

  const member = props.member ?? {
    id: "",
    number: "",
    customer_type: "",
    company_name: "",
    identification_number: "",
    given_name: "",
    family_name: "",
    email: "",
    phone: "",
    billing_address: {
      street_address: "",
      street_address2: "",
      postal_code: "",
      city: "",
      country_code: "",
      region: "",
      care_of: "",
    },
    origin: "",
    date_verified: "",
    is_valid_customer: true,
  };

  const isCompany = member.customer_type === CustomerType.COMPANY;

  return (
    <Card<MemberDetailCardFormValues>
      columns={6}
      isEditable={hasPermission(user, "member.change_member")}
      onSubmit={handleSave}
    >
      <CardHeader title={t("Contact Details")} />

      <CardContent>
        {isCompany && (
          <CardRow>
            <CardFieldText
              error={Boolean(fieldErrors.company_name)}
              formName="company_name"
              helperText={fieldErrors.company_name}
              label={t("Company Name")}
              required={isCompany}
              size={3}
              value={member.company_name}
            />

            <CardFieldText
              disabled={!isCompany}
              error={Boolean(fieldErrors.identification_number)}
              formName="identification_number"
              helperText={fieldErrors.identification_number}
              label={t("Organization Number")}
              size={3}
              value={member.identification_number ?? ""}
            />
          </CardRow>
        )}

        <CardRow>
          <CardFieldText
            error={Boolean(fieldErrors.given_name)}
            formName="given_name"
            helperText={fieldErrors.given_name}
            label={isCompany ? t("Contact") + ": " + t("First Name") : t("First Name")}
            required={!isCompany}
            size={3}
            value={member.given_name}
          />

          <CardFieldText
            error={Boolean(fieldErrors.family_name)}
            formName="family_name"
            helperText={fieldErrors.family_name}
            label={t("Last Name")}
            required={!isCompany}
            size={3}
            value={member.family_name}
          />
        </CardRow>

        <CardRow>
          <CardFieldText
            required
            error={Boolean(fieldErrors.email)}
            formName="email"
            helperText={fieldErrors.email}
            label={t("Email")}
            size={3}
            value={member.email}
          />
          <CardFieldText
            error={Boolean(fieldErrors.phone)}
            formName="phone"
            helperText={fieldErrors.phone}
            label={t("Phone")}
            size={3}
            value={member.phone}
          />
        </CardRow>

        {!isCompany && member.identification_number && (
          <CardRow>
            <CardFieldText
              disabled={!isCompany}
              error={Boolean(fieldErrors.identification_number)}
              formName="identification_number"
              helperText={fieldErrors.identification_number}
              label={t("SSN")}
              size={6}
              value={member.identification_number ?? ""}
            />
          </CardRow>
        )}

        <CardRow>
          <CardFieldAddress
            fieldErrors={{
              street_address: fieldErrors.street_address,
              street_address2: fieldErrors.street_address2,
              postal_code: fieldErrors.postal_code,
              city: fieldErrors.city,
              country_code: fieldErrors.country_code,
              region: fieldErrors.region,
              care_of: fieldErrors.care_of,
            }}
            formName="billing_address"
            isCompany={isCompany}
            isEditable={hasPermission(user, "member.change_memberaddress")}
            label={t("Billing Address")}
            required={isCompany}
            value={member.billing_address}
          />
        </CardRow>
      </CardContent>

      <CardActions>
        <CardCancelButton />
        <CardSaveButton />
      </CardActions>
    </Card>
  );
};
