import { JsonObject, mergeObjects } from '@win2win/shared';
import { useFetch } from '@win2win/shared-ui';
import { omit, orderBy } from 'lodash';
import moment from 'moment-timezone';
import { notifyError } from 'src/helpers';
import { computed, reactive, Ref, watch } from 'vue';

const DEFAULT_FIELDS: ContactField[] = ['nombre', 'apellido', 'apellido2', 'email', 'telefono', 'telefono2', 'fecha_nacimiento', 'identificacion', 'roles'];

export function useContactoModel(idContacto: Ref<number | null>, idCaptacion: number | null = null, fields: ContactField[] = DEFAULT_FIELDS, defaultValues?: JsonObject) {
  const fieldsHash = orderBy(fields).join(',');
  const model = reactive<ContactoModel>(getDefaultContactoModel(defaultValues));
  const key = computed(() => ['contacto', { idContacto: idContacto.value, idCaptacion, fields: fieldsHash }]);
  const query = computed(() => `w2w-query/contacto(${idContacto.value})->(telefonos,ubicacion->(zona(id=ubicacion.id_zona),pais(id=ubicacion.id_pais)))`);
  const { data: contacto, fetching, invalidate: refetch } = useFetch<Contacto>(key, query, undefined, undefined, { enabled: computed(() => !!idContacto.value) });

  const validate = () => {
    let message = '';
    if (!model.nombre && !model.razon_social) {
      message = 'El nombre es requerido';
    }
    if (message) {
      notifyError(null, message);
      return false;
    }
    return true;
  };

  const formatData = () => {
    const CONTACTO = {
      ID_CAPTACION: model.id_captacion ?? idCaptacion,
      ID_CONTACTO: idContacto.value,
    } as any;
    if (fields.includes('razon_social')) CONTACTO['RAZON_SOCIAL'] = model.razon_social;
    if (fields.includes('nombre')) CONTACTO['NOMBRE'] = model.nombre;
    if (fields.includes('apellido')) CONTACTO['APELLIDO'] = model.apellido;
    if (fields.includes('apellido2')) CONTACTO['APELLIDO2'] = model.apellido2;
    if (fields.includes('curp')) CONTACTO['CURP'] = model.curp;
    if (fields.includes('rfc')) CONTACTO['RFC'] = model.rfc;
    if (fields.includes('email')) CONTACTO['EMAIL'] = model.email;
    if (fields.includes('iban')) CONTACTO['IBAN'] = model.iban;
    if (fields.includes('persona_contacto')) CONTACTO['PERSONA_CONTACTO'] = model.persona_contacto;
    if (fields.includes('seguridad_social')) CONTACTO['SEGURIDAD_SOCIAL'] = model.seguridad_social;
    if (fields.includes('sexo_biologico')) CONTACTO['SEXO_BIOLOGICO'] = model.sexo_biologico;
    if (fields.includes('nacionalidad')) CONTACTO['NACIONALIDAD'] = model.nacionalidad;
    if (fields.includes('fecha_nacimiento')) CONTACTO['FECHA_NACIMIENTO'] = model.fecha_nacimiento ? moment(model.fecha_nacimiento, 'DD/MM/YYYY').format('YYYY-MM-DD') : null;
    if (fields.includes('roles')) CONTACTO['ROLES'] = model.roles?.map((r) => r.toLowerCase()) || [];

    let UBICACION: any = null;
    UBICACION = {
      ID_CONTACTO: idContacto.value,
      ID_UBICACION: contacto.value?.ubicacion?.id || null,
      ID_ZONA: model.zona,
      ID_PAIS: model.pais,
      CALLE: model?.calle,
      CIUDAD: model?.ciudad,
      MUNICIPIO: model?.municipio,
      COLONIA: model?.colonia,
      NUMERO: Number(model?.numero),
      COD_POSTAL: model?.cod_postal,
      ESTADO: 1,
    };
    if (fields.includes('identificacion')) {
      CONTACTO['TIPO_DOC'] = model.tipo_identificacion;
      CONTACTO['NUMERO_DOC'] = model.identificacion;
    }
    const TELEFONOS: any[] = [];
    if (fields.includes('telefono'))
      TELEFONOS.push({
        ID_CONTACTO_TEL: contacto.value?.telefonos?.[0]?.id || null,
        ID_CONTACTO: idContacto.value,
        NUMERO: model.telefono,
        NOMBRE: model.nombre,
      });
    if (fields.includes('telefono2'))
      TELEFONOS.push({
        ID_CONTACTO_TEL: contacto.value?.telefonos?.[1]?.id || null,
        ID_CONTACTO: idContacto.value,
        NUMERO: model.telefono2,
        NOMBRE: model.nombre,
      });
    if (fields.includes('whatsapp'))
      TELEFONOS.push({
        ID_CONTACTO_TEL: contacto.value?.telefonos?.[2]?.id || null,
        ID_CONTACTO: idContacto.value,
        NUMERO: model.whatsapp,
        NOMBRE: model.nombre,
      });

    return {
      CONTACTO,
      TELEFONOS,
      UBICACION,
    };
  };

  function setModel(value?: Contacto | null) {
    if (!value) return;
    Object.assign(
      model,
      mergeObjects(
        {
          ...omit(value, 'telefonos', 'zona', 'pais'),
          fecha_nacimiento: value.fecha_nacimiento ? moment(value.fecha_nacimiento).format('DD/MM/YYYY') : '',
          telefono: value.telefonos[0]?.numero || '',
          telefono2: value.telefonos[1]?.numero || '',
          whatsapp: value.telefonos[2]?.numero || '',
          zona: value?.ubicacion?.zona?.id || null,
          calle: value?.ubicacion?.calle || null,
          ciudad: value?.ubicacion?.ciudad || null,
          municipio: value?.ubicacion?.municipio || '',
          colonia: value?.ubicacion?.colonia || '',
          entre_calle: value?.ubicacion?.entre_calle || '',
          entre_calle2: value?.ubicacion?.entre_calle2 || '',
          cod_postal: value?.ubicacion?.cod_postal || null,
          numero: value?.ubicacion?.numero || null,
          pais: value.ubicacion?.pais?.id || null,
        },
        defaultValues || {},
        { emptyValues: [null, ''] }
      )
    );
  }

  const resetModel = () => setModel(contacto.value);
  watch(contacto, (value) => setModel(value), { immediate: true });

  return { fetching, model, refetch, validate, formatData, resetModel };
}

export interface Contacto {
  id_captacion: number | null;
  nombre: string;
  apellido: string;
  apellido2: string;
  email: string;
  fecha_nacimiento: string;
  identificacion: string;
  tipo_identificacion: number | null;
  pagina_web: string;
  razon_social: string;
  curp: string;
  rfc: string;
  calle?: string;
  numero?: string;
  ciudad?: string;
  cod_postal?: string;
  iban?: string;
  sexo_biologico?: string;
  seguridad_social?: string;
  nacionalidad?: string;
  roles: string[];
  id?: number;

  telefonos: { id: number; numero: string }[];
  ubicacion?: {
    id?: number;
    calle?: string;
    numero?: string;
    ciudad?: string;
    cod_postal?: string;
    municipio?: string;
    colonia?: string;
    entre_calle?: string;
    entre_calle2?: string;
    zona?: {
      id: number;
      nombre: string;
    };
    pais?: {
      id: number;
      nombre: string;
    };
  };
}

export type ContactoModel = Record<ContactField, any>;

const getDefaultContactoModel = (defaultData: Partial<ContactoModel> = {}) =>
  ({
    id: undefined,
    id_captacion: null,
    nombre: '',
    apellido: '',
    apellido2: '',
    email: '',
    telefono: '',
    telefono2: '',
    whatsapp: '',
    calle: '',
    numero: '',
    ciudad: '',
    municipio: '',
    entre_calle: '',
    entre_calle2: '',
    colonia: '',
    cod_postal: '',
    fecha_nacimiento: '',
    identificacion: '',
    pagina_web: '',
    curp: '',
    rfc: '',
    foto: '',
    razon_social: '',
    persona_contacto: '',
    iban: '',
    sexo_biologico: '',
    seguridad_social: '',
    nacionalidad: '',
    roles: [],
    tipo_identificacion: null,
    estado_civil: null,
    hijos: null,
    pais: null,
    zona: null,
    props: null,
    ...defaultData,
  } as ContactoModel);

export type ContactField =
  | 'id'
  | 'id_captacion'
  | 'nombre'
  | 'apellido'
  | 'apellido2'
  | 'email'
  | 'telefono'
  | 'telefono2'
  | 'whatsapp'
  | 'fecha_nacimiento'
  | 'tipo_identificacion'
  | 'identificacion'
  | 'persona_contacto'
  | 'razon_social'
  | 'pagina_web'
  | 'roles'
  | 'pais'
  | 'cod_postal'
  | 'pais_zona'
  | 'props'
  | 'curp'
  | 'rfc'
  | 'extranjero'
  | 'calle'
  | 'numero'
  | 'zona'
  | 'ciudad'
  | 'codigo'
  | 'codigo_postal'
  | 'entre_calle'
  | 'entre_calle2'
  | 'colonia'
  | 'municipio'
  | 'nacionalidad'
  | 'sexo_biologico'
  | 'seguridad_social'
  | 'iban'
  | 'estado_civil'
  | 'hijos'
  | 'ubicacion';
